예제 #1
0
        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);
        }
예제 #2
0
        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;
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
 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));
 }
예제 #7
0
 public RelationContainer(DataElement parent)
 {
     this.parent = parent;
 }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
0
 public RelativeBinding(OffsetRelation rel, DataElement parent)
     : base(parent)
 {
     this.rel = rel;
 }
예제 #11
0
        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);
            }
        }
예제 #12
0
파일: Data.cs 프로젝트: 751620780/Peach
        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;
            }
        }
예제 #13
0
파일: String.cs 프로젝트: 751620780/Peach
        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);
        }
예제 #14
0
 public void SelectDefault()
 {
     Clear();
     this.Add(random.Choice(choiceElements).Value);
     _selectedElement = this[0];
 }
예제 #15
0
 public void SelectDefault()
 {
     this.Clear();
     this.Add(choiceElements[0]);
     _selectedElement = this[0];
 }
예제 #16
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;
                            }
                        }
                    }
                }
            }
        }
예제 #17
0
        /// <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);
        }
예제 #18
0
            private bool InSourceGraph(DataElement elem)
            {
                var top = root.getRoot();

                return(elem == top || elem.isChildOf(top));
            }
예제 #19
0
        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);
            }
        }
예제 #20
0
 public SizeRelation(DataElement parent)
     : base(parent)
 {
 }
예제 #21
0
 public CountRelation(DataElement parent)
     : base(parent)
 {
 }