public static DataElement PitParser(PitParser context, XmlNode node, DataElementContainer parent) { if (node.Name != "XmlAttribute" || !(parent is XmlElement)) { return(null); } var xmlAttribute = DataElement.Generate <XmlAttribute>(node); xmlAttribute.attributeName = node.getAttrString("attributeName"); if (node.hasAttr("ns")) { xmlAttribute.ns = node.getAttrString("ns"); } context.handleCommonDataElementAttributes(node, xmlAttribute); context.handleCommonDataElementChildren(node, xmlAttribute); context.handleDataElementContainer(node, xmlAttribute); return(xmlAttribute); }
private void OnDeserialized(StreamingContext context) { DataElement.CloneContext ctx = context.Context as DataElement.CloneContext; if (ctx == null) { return; } System.Diagnostics.Debug.Assert(_fullNames != null); if (_of == null && !string.IsNullOrEmpty(_fullNames.of)) { System.Diagnostics.Debug.Assert(ctx.elements.ContainsKey(_fullNames.of)); _of = ctx.elements[_fullNames.of]; _of.relations.Add(this, false); } if (_from == null && !string.IsNullOrEmpty(_fullNames.from)) { System.Diagnostics.Debug.Assert(ctx.elements.ContainsKey(_fullNames.from)); _from = ctx.elements[_fullNames.from]; _from.relations.Add(this, false); } if (_parent == null && !string.IsNullOrEmpty(_fullNames.parent)) { System.Diagnostics.Debug.Assert(ctx.elements.ContainsKey(_fullNames.parent)); _parent = ctx.elements[_fullNames.parent]; } // Must always re-subscribe the invalidated event on deserialize if (_of != null) { _of.Invalidated += new InvalidatedEventHandler(OfInvalidated); } _fullNames = null; }
public static DataElement PitParser(PitParser context, XmlNode node, DataElementContainer parent) { if (node.Name != "Blob") { return(null); } var blob = DataElement.Generate <Blob>(node); context.handleCommonDataElementAttributes(node, blob); context.handleCommonDataElementChildren(node, blob); context.handleCommonDataElementValue(node, blob); if (blob.DefaultValue == null) { blob.DefaultValue = new Variant(new byte[0]); } if (blob.DefaultValue.GetVariantType() == Variant.VariantType.String) { blob.DefaultValue = new Variant(ASCIIEncoding.ASCII.GetBytes((string)blob.DefaultValue)); } if (blob.hasLength) { BitStream bs = (BitStream)blob.DefaultValue; if (bs.LengthBits > blob.lengthAsBits) { throw new PeachException("Error, value of " + blob.debugName + " is longer than specified length."); } else if (bs.LengthBits < blob.lengthAsBits) { ExpandDefaultValue(blob, bs); } } return(blob); }
public new static DataElement PitParser(PitParser context, XmlNode node, DataElementContainer parent) { var array = DataElement.Generate <Array>(node); if (node.hasAttr("minOccurs")) { array.minOccurs = node.getAttrInt("minOccurs"); array.maxOccurs = -1; array.occurs = array.minOccurs; } if (node.hasAttr("maxOccurs")) { array.maxOccurs = node.getAttrInt("maxOccurs"); } if (node.hasAttr("occurs")) { array.occurs = node.getAttrInt("occurs"); } return(array); }
public static DataElement PitParser(PitParser context, XmlNode node, DataElementContainer parent) { if (node.Name != "Choice") { return(null); } Choice choice = DataElement.Generate <Choice>(node); context.handleCommonDataElementAttributes(node, choice); context.handleCommonDataElementChildren(node, choice); context.handleDataElementContainer(node, choice); // Move children to choiceElements collection foreach (DataElement elem in choice) { choice.choiceElements.Add(elem.name, elem); elem.parent = choice; } choice.Clear(false); return(choice); }
private static string FmtMessage(Relation r, DataElement obj, string who) { return(string.Format("Relation Of=\"{0}\" From=\"{1}\" not {2}element \"{3}\"", r.Of.fullName, r.From.fullName, who, obj.fullName)); }
public RelationContainer(DataElement parent) { this.parent = parent; }
public static DataElement PitParser(PitParser context, XmlNode node, DataElementContainer parent) { if (node.Name != "Number") { return(null); } var num = DataElement.Generate <Number>(node); if (node.hasAttr("signed")) { num.Signed = node.getAttrBool("signed"); } else { num.Signed = context.getDefaultAttr(typeof(Number), "signed", num.Signed); } if (node.hasAttr("size")) { int size = node.getAttrInt("size"); if (size < 1 || size > 64) { throw new PeachException(string.Format("Error, unsupported size '{0}' for {1}.", size, num.debugName)); } num.lengthType = LengthType.Bits; num.length = size; } string strEndian = null; if (node.hasAttr("endian")) { strEndian = node.getAttrString("endian"); } if (strEndian == null) { strEndian = context.getDefaultAttr(typeof(Number), "endian", null); } if (strEndian != null) { switch (strEndian.ToLower()) { case "little": num.LittleEndian = true; break; case "big": num.LittleEndian = false; break; case "network": num.LittleEndian = false; break; default: throw new PeachException( string.Format("Error, unsupported value '{0}' for 'endian' attribute on {1}.", strEndian, num.debugName)); } } context.handleCommonDataElementAttributes(node, num); context.handleCommonDataElementChildren(node, num); context.handleCommonDataElementValue(node, num); return(num); }
public static DataElement PitParser(PitParser context, XmlNode node, DataElementContainer parent) { if (node.Name != "Flags") { return(null); } var flags = DataElement.Generate <Flags>(node); string strSize = null; if (node.hasAttr("size")) { strSize = node.getAttrString("size"); } if (strSize == null) { strSize = context.getDefaultAttr(typeof(Flags), "size", null); } if (strSize == null) { throw new PeachException("Error, Flags elements must have 'size' attribute!"); } int size; if (!int.TryParse(strSize, out size)) { throw new PeachException("Error, " + flags.name + " size attribute is not valid number."); } if (size < 1 || size > 64) { throw new PeachException(string.Format("Error, unsupported size '{0}' for {1}.", size, flags.debugName)); } flags.lengthType = LengthType.Bits; flags.length = size; string strEndian = null; if (node.hasAttr("endian")) { strEndian = node.getAttrString("endian"); } if (strEndian == null) { strEndian = context.getDefaultAttr(typeof(Flags), "endian", null); } if (strEndian != null) { switch (strEndian.ToLower()) { case "little": flags.LittleEndian = true; break; case "big": flags.LittleEndian = false; break; case "network": flags.LittleEndian = false; break; default: throw new PeachException( string.Format("Error, unsupported value '{0}' for 'endian' attribute on {1}.", strEndian, flags.debugName)); } } context.handleCommonDataElementAttributes(node, flags); context.handleCommonDataElementChildren(node, flags); foreach (XmlNode child in node.ChildNodes) { // Looking for "Flag" element if (child.Name == "Flag") { flags.Add(Flag.PitParser(context, child, flags)); } } return(flags); }
public RelativeBinding(OffsetRelation rel, DataElement parent) : base(parent) { this.rel = rel; }
private void OnSerializing(StreamingContext context) { DataElement.CloneContext ctx = context.Context as DataElement.CloneContext; if (ctx == null) { return; } if (DataElement.DebugClone) { logger.Debug("Serializing From={0}, Of={1}", _of == null ? "(null) " + _ofName : _of.fullName, _from == null ? "(null) " + _fromName : _from.fullName); } System.Diagnostics.Debug.Assert(_fullNames == null); System.Diagnostics.Debug.Assert(!ctx.metadata.ContainsKey(this)); string relName; _fullNames = new FullNames(); Metadata m = new Metadata(); if (ctx.rename.Contains(_of)) { m.ofName = _ofName; _ofName = ctx.newName; } else if (_of != null && !_of.isChildOf(ctx.root, out relName)) { _fullNames.of = relName; ctx.elements[_fullNames.of] = _of; m.of = _of; _of = null; } else if (_ofName == ctx.oldName && parent.find(_ofName) == null) { if (_of == null && ctx.oldName == _ofName) { _of = ctx.root; } m.ofName = _ofName; _ofName = ctx.newName; } if (ctx.rename.Contains(_from)) { m.fromName = _fromName; _fromName = ctx.newName; } else if (_from != null && !_from.isChildOf(ctx.root, out relName)) { _fullNames.from = relName; ctx.elements[_fullNames.from] = _from; m.from = _from; _from = null; } else if (_fromName == ctx.oldName && parent.find(_fromName) == null) { if (_from == null && ctx.oldName == _fromName) { _from = ctx.root; } m.fromName = _fromName; _fromName = ctx.newName; } if (ctx.rename.Contains(_parent)) { if (_of == null && _ofName == ctx.oldName) { m.ofName = _ofName; _ofName = ctx.newName; } if (_from == null && _fromName == ctx.oldName) { m.fromName = _fromName; _fromName = ctx.newName; } } else if (_parent != null && !_parent.isChildOf(ctx.root, out relName)) { _fullNames.parent = relName; ctx.elements[_fullNames.parent] = _parent; m.parent = _parent; _parent = null; } if (m.from != null || m.of != null || m.parent != null || m.ofName != null || m.fromName != null) { ctx.metadata.Add(this, m); } }
static void ApplyField(DataElementContainer model, string field, Variant value) { DataElement elem = model; DataElementContainer container = model; var names = field.Split('.'); for (int i = 0; i < names.Length; i++) { string name = names[i]; Match m = Regex.Match(name, @"(.*)\[(-?\d+)\]$"); if (m.Success) { name = m.Groups[1].Value; int index = int.Parse(m.Groups[2].Value); if (!container.ContainsKey(name)) { throw new PeachException("Error, unable to resolve field \"" + field + "\" against \"" + model.fullName + "\"."); } var array = container[name] as Array; if (array == null) { throw new PeachException("Error, cannot use array index syntax on field name unless target element is an array. Field: " + field); } // Are we disabling this array? if (index == -1) { if (array.minOccurs > 0) { throw new PeachException("Error, cannot set array to zero elements when minOccurs > 0. Field: " + field + " Element: " + array.fullName); } // Remove all children array.Clear(); return; } if (array.maxOccurs != -1 && index > array.maxOccurs) { throw new PeachException("Error, index larger that maxOccurs. Field: " + field + " Element: " + array.fullName); } if (!array.hasExpanded && array.origionalElement == null) { array.origionalElement = array[0]; array.RemoveAt(0); } // Add elements upto our index for (int x = array.Count; x <= index; x++) { string itemName = array.origionalElement.name + "_" + x; var item = array.origionalElement.Clone(itemName); array.Add(item); } array.hasExpanded = true; elem = array[index]; container = elem as DataElementContainer; } else if (container is Choice) { elem = null; var choice = container as Choice; if (!choice.choiceElements.TryGetValue(name, out elem)) { throw new PeachException("Error, unable to resolve field \"" + field + "\" against \"" + model.fullName + "\"."); } container = elem as DataElementContainer; choice.SelectedElement = elem; } else { if (!container.ContainsKey(name)) { throw new PeachException("Error, unable to resolve field \"" + field + "\" against \"" + model.fullName + "\"."); } elem = container[name]; container = elem as DataElementContainer; } } if (!(elem is DataElementContainer)) { elem.DefaultValue = value; } }
public static DataElement PitParser(PitParser context, XmlNode node, DataElementContainer parent) { if (node.Name != "String") { return(null); } var str = DataElement.Generate <String>(node); if (node.hasAttr("nullTerminated")) { str.nullTerminated = node.getAttrBool("nullTerminated"); } else { str.nullTerminated = context.getDefaultAttr(typeof(String), "nullTerminated", str.nullTerminated); } string type = "ascii"; if (node.hasAttr("type")) { type = node.getAttrString("type"); } else { type = context.getDefaultAttr(typeof(String), "type", type); } StringType stringType; if (!Enum.TryParse <StringType>(type, true, out stringType)) { throw new PeachException("Error, unknown String type '" + type + "' on element '" + str.name + "'."); } str.stringType = stringType; if (node.hasAttr("padCharacter")) { str.padCharacter = node.getAttrChar("padCharacter"); } else { str.padCharacter = context.getDefaultAttr(typeof(String), "padCharacter", str.padCharacter); } if (node.hasAttr("tokens")) // This item has a default! { throw new NotSupportedException("Tokens attribute is depricated in Peach 3. Use parameter to StringToken analyzer isntead."); } if (node.hasAttr("analyzer")) // this should be passed via a child element me things! { throw new NotSupportedException("Analyzer attribute is depricated in Peach 3. Use a child element instead."); } context.handleCommonDataElementAttributes(node, str); context.handleCommonDataElementChildren(node, str); context.handleCommonDataElementValue(node, str); if (!node.hasAttr("value")) { str.DefaultValue = new Variant(""); } return(str); }
public void SelectDefault() { Clear(); this.Add(random.Choice(choiceElements).Value); _selectedElement = this[0]; }
public void SelectDefault() { this.Clear(); this.Add(choiceElements[0]); _selectedElement = this[0]; }
public void GenerateBoundaryFile(string filename) { long pos = 0; Stack <DataElement> stack = new Stack <DataElement>(); using (System.IO.StreamWriter outputFile = new System.IO.StreamWriter(filename)) { DataElement root = this; stack.Push(this); // Execute the loop until all data elements (nodes) are traversed while (stack.Count > 0) { DataElement node = stack.Pop(); // If the current node is a DataElementContainer, get all child nodes and push // them on top of the stack if (node is DataElementContainer) { // Output the name of the current node and its boundary string strName = node.name; DataElement ancestor = node.parent; while (ancestor != null) { strName = ancestor.name + "~" + strName; ancestor = ancestor.parent; } if (node.isMutable) { outputFile.WriteLine("{0},{1},{2},{3}", pos, pos + node.Value.LengthBytes - 1, strName, "Enabled"); } else { outputFile.WriteLine("{0},{1},{2},{3}", pos, pos + node.Value.LengthBytes - 1, strName, "Disabled"); } //Console.WriteLine ("Processing node: {0}", node.name); DataElementContainer container = (DataElementContainer)node; if (container.Count > 0) { for (int i = container.Count - 1; i >= 0; i--) { //Console.WriteLine ("Pushing to stack: {0}", container [i].name); stack.Push(container [i]); } } } else { // Output the name of the current node and its boundary // in case the node is mutable if (node.Value.LengthBytes > 0) { if (node.isMutable) { string strName = node.name; DataElement ancestor = node.parent; while (ancestor != null) { strName = ancestor.name + "~" + strName; ancestor = ancestor.parent; } outputFile.WriteLine("{0},{1},{2},{3}", pos, pos + node.Value.LengthBytes - 1, strName, "Enabled"); pos += node.Value.LengthBytes; } else { // If the Data Element is not mutable, just update the position //Console.WriteLine ("DataElement: {0} is not mutable", node.name); string strName = node.name; DataElement ancestor = node.parent; while (ancestor != null) { strName = ancestor.name + "~" + strName; ancestor = ancestor.parent; } outputFile.WriteLine("{0},{1},{2},{3}", pos, pos + node.Value.LengthBytes - 1, strName, "Disabled"); pos += node.Value.LengthBytes; } } } } } }
/// <summary> /// Caluclate the offset in bytes between two data elements. /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <returns>Returns the offset in bits between two elements. Return can be negative.</returns> protected long calculateOffset(DataElement from, DataElement to) { DataElementContainer commonAncestor = null; long fromPosition = 0; long toPosition = 0; if (isRelativeOffset) { if (!string.IsNullOrEmpty(relativeTo)) { DataElement relative = from.find(relativeTo); if (relative == null) { throw new PeachException(string.Format("Error, offset relation from element '{0}' couldn't locate relative to element '{1}'.", from.fullName, relativeTo)); } from = relative; } commonAncestor = findCommonRoot(from, to); if (commonAncestor == null) { throw new PeachException("Error, unable to calculate offset between '" + from.fullName + "' and '" + to.fullName + "'."); } BitStream stream = commonAncestor.Value; if (from != commonAncestor) { if (!stream.HasDataElement(from.fullName)) { throw new PeachException("Error, unable to calculate offset between '" + from.fullName + "' and '" + to.fullName + "'."); } fromPosition = stream.DataElementPosition(from); } if (!stream.HasDataElement(to.fullName)) { throw new PeachException("Error, unable to calculate offset between '" + from.fullName + "' and '" + to.fullName + "'."); } toPosition = stream.DataElementPosition(to); } else { commonAncestor = findCommonRoot(from, to); if (commonAncestor == null) { throw new PeachException("Error, unable to calculate offset between '" + from.fullName + "' and '" + to.fullName + "'."); } BitStream stream = commonAncestor.Value; fromPosition = 0; if (!stream.HasDataElement(to.fullName)) { throw new PeachException("Error, unable to calculate offset between '" + from.fullName + "' and '" + to.fullName + "'."); } toPosition = stream.DataElementPosition(to); } return(toPosition - fromPosition); }
private bool InSourceGraph(DataElement elem) { var top = root.getRoot(); return(elem == top || elem.isChildOf(top)); }
public override void Crack(DataCracker context, BitStream data, long?size) { long startPos = data.TellBits(); BitStream sizedData = ReadSizedData(data, size); if (this.Count > 0) { origionalElement = this[0]; Clear(false); } long min = minOccurs; long max = maxOccurs; var rel = relations.Of <CountRelation>().Where(context.HasCracked).FirstOrDefault(); if (rel != null) { min = max = rel.GetValue(); } else if (minOccurs == 1 && maxOccurs == 1) { min = max = occurs; } if (((min > maxOccurs && maxOccurs != -1) || (min < minOccurs)) && min != occurs) { string msg = "{0} has invalid count of {1} (minOccurs={2}, maxOccurs={3}, occurs={4}).".Fmt( debugName, min, minOccurs, maxOccurs, occurs); throw new CrackingFailure(msg, this, data); } for (int i = 0; max == -1 || i < max; ++i) { logger.Debug("Crack: ======================"); logger.Debug("Crack: {0} Trying #{1}", origionalElement.debugName, i + 1); long pos = sizedData.TellBits(); if (pos == sizedData.LengthBits) { logger.Debug("Crack: Consumed all bytes. {0}", sizedData.Progress); break; } var clone = makeElement(i); Add(clone); try { context.CrackData(clone, sizedData); // If we used 0 bytes and met the minimum, we are done if (pos == sizedData.TellBits() && i == min) { RemoveAt(clone.parent.IndexOf(clone)); break; } } catch (CrackingFailure) { logger.Debug("Crack: {0} Failed on #{1}", debugName, i + 1); // If we couldn't satisfy the minimum propigate failure if (i < min) { throw; } RemoveAt(clone.parent.IndexOf(clone)); sizedData.SeekBits(pos, System.IO.SeekOrigin.Begin); break; } } if (this.Count < min) { string msg = "{0} only cracked {1} of {2} elements.".Fmt(debugName, Count, min); throw new CrackingFailure(msg, this, data); } if (size.HasValue && data != sizedData) { data.SeekBits(startPos + sizedData.TellBits(), System.IO.SeekOrigin.Begin); } }
public SizeRelation(DataElement parent) : base(parent) { }
public CountRelation(DataElement parent) : base(parent) { }