Example #1
0
        void handleConstraint(DataElement element, BitStream data)
        {
            logger.Debug("Running constraint [" + element.constraint + "]");

            Dictionary <string, object> scope = new Dictionary <string, object>();

            scope["element"] = element;

            var iv = element.InternalValue;

            if (iv.GetVariantType() == Variant.VariantType.ByteString || iv.GetVariantType() == Variant.VariantType.BitStream)
            {
                scope["value"] = (byte[])iv;
                logger.Debug("Constraint, value=byte array.");
            }
            else
            {
                scope["value"] = (string)iv;
                logger.Debug("Constraint, value=[" + (string)iv + "].");
            }

            object oReturn = Scripting.EvalExpression(element.constraint, scope);

            if (!((bool)oReturn))
            {
                throw new CrackingFailure("Constraint failed.", element, data);
            }
        }
Example #2
0
        public override long GetValue()
        {
            if (_isRecursing)
            {
                return(0);
            }

            try
            {
                _isRecursing = true;
                long size = (long)From.DefaultValue;

                if (_expressionGet != null)
                {
                    Dictionary <string, object> state = new Dictionary <string, object>();
                    state["size"]  = size;
                    state["value"] = size;
                    state["self"]  = From;

                    object value = Scripting.EvalExpression(_expressionGet, state);
                    size = Convert.ToInt64(value);
                }

                if (lengthType == LengthType.Bytes)
                {
                    size = size * 8;
                }

                return(size);
            }
            finally
            {
                _isRecursing = false;
            }
        }
Example #3
0
        protected override Variant fixupImpl()
        {
            if (_pythonFixup == null)
            {
                Dictionary <string, object> state = new Dictionary <string, object>();
                state["fixupSelf"] = this;

                _pythonFixup = Scripting.EvalExpression(
                    string.Format("{0}(fixupSelf)",
                                  (string)args["class"]),
                    state);
            }

            var from = elements["ref"];

            logger.Debug("fixupImpl(): ref: " + from.GetHashCode().ToString());

            object data = _pythonFixup.fixup(from);

            if (data is byte[])
            {
                return(new Variant((byte[])data));
            }
            else if (data is string)
            {
                return(new Variant((string)data));
            }
            else if (data is int)
            {
                return(new Variant((int)data));
            }

            logger.Error("Error, unknown type [" + data.GetType().ToString() + "].");
            throw new ApplicationException("Error, unknown type [" + data.GetType().ToString() + "].");
        }
Example #4
0
        public ScriptFixup(DataElement parent, Dictionary <string, Variant> args)
            : base(parent, args, "ref")
        {
            try
            {
                Dictionary <string, object> state = new Dictionary <string, object>();
                state["fixupSelf"] = this;

                _pythonFixup = Scripting.EvalExpression(
                    string.Format("{0}(fixupSelf)",
                                  (string)args["class"]),
                    state);

                if (_pythonFixup == null)
                {
                    throw new PeachException("Error, unable to create an instance of the \"" + (string)args["class"] + "\" script class.");
                }

                logger.Debug("ScriptFixup(): _pythonFixup != null");
            }
            catch (Exception ex)
            {
                logger.Debug("class: " + (string)args["class"]);
                logger.Error(ex.Message);
                throw;
            }
        }
Example #5
0
        public override long GetValue()
        {
            if (_isRecursing)
            {
                return(0);
            }

            try
            {
                _isRecursing = true;
                long offset = (long)From.DefaultValue;

                if (_expressionGet != null)
                {
                    Dictionary <string, object> state = new Dictionary <string, object>();
                    state["offset"] = offset;
                    state["value"]  = offset;
                    state["self"]   = this._parent;

                    object value = Scripting.EvalExpression(_expressionGet, state);
                    offset = Convert.ToInt64(value);
                }

                return(offset);
            }
            finally
            {
                _isRecursing = false;
            }
        }
Example #6
0
        public object CallMethod(string method, object[] args)
        {
            if (comObject == null)
            {
                throw new Exception("Error, please call Initalize first!");
            }

            Dictionary <string, object> state = new Dictionary <string, object>();

            state["ComObject"] = comObject;

            string cmd = "ComObject." + method + "(";

            int count = 0;

            foreach (object arg in args)
            {
                state["ComArgs_" + count] = arg;
                cmd += "ComArgs_" + count + ",";
                count++;
            }

            if (count > 0)
            {
                // Remove that last comma :)
                cmd = cmd.Substring(0, cmd.Length - 1);
            }

            cmd += ")";

            return(Scripting.EvalExpression(cmd, state));
        }
Example #7
0
        public override Variant CalculateFromValue()
        {
            if (_isRecursing)
            {
                return(new Variant(0));
            }

            try
            {
                if (Of == null)
                {
                    logger.Error("Error, Of returned null");
                    return(null);
                }

                _isRecursing = true;
                long size = Of.Value.LengthBits;

                if (lengthType == LengthType.Bytes)
                {
                    if (_expressionSet != null)
                    {
                        Dictionary <string, object> state = new Dictionary <string, object>();
                        state["size"]  = size / 8;
                        state["value"] = size / 8;
                        state["self"]  = From;

                        object newValue = Scripting.EvalExpression(_expressionSet, state);
                        size = Convert.ToInt64(newValue) * 8;
                    }

                    size = size / 8;
                }
                else
                {
                    if (_expressionSet != null)
                    {
                        Dictionary <string, object> state = new Dictionary <string, object>();
                        state["size"]  = size;
                        state["value"] = size;
                        state["self"]  = From;

                        object newValue = Scripting.EvalExpression(_expressionSet, state);
                        size = Convert.ToInt64(newValue);
                    }
                }

                return(new Variant(size));
            }
            finally
            {
                _isRecursing = false;
            }
        }
Example #8
0
        public override Variant CalculateFromValue()
        {
            if (_isRecursing)
            {
                return(new Variant(0));
            }

            try
            {
                _isRecursing = true;

                if (Of == null)
                {
                    logger.Error("Error, Of returned null");
                    return(null);
                }

                Array OfArray = Of as Array;

                if (OfArray == null)
                {
                    logger.Error(
                        string.Format("Count Relation requires '{0}' to be an array.  Set the minOccurs and maxOccurs properties.",
                                      OfName));

                    return(null);
                }

                int count = OfArray.Count;

                // Allow us to override the count of the array
                if (OfArray.overrideCount.HasValue)
                {
                    count = (int)OfArray.overrideCount;
                }

                if (_expressionSet != null)
                {
                    Dictionary <string, object> state = new Dictionary <string, object>();
                    state["count"] = count;
                    state["value"] = count;
                    state["self"]  = this._parent;

                    object value = Scripting.EvalExpression(_expressionSet, state);
                    count = Convert.ToInt32(value);
                }

                return(new Variant(count));
            }
            finally
            {
                _isRecursing = false;
            }
        }
Example #9
0
        public void SetProperty(string property, object value)
        {
            if (comObject == null)
            {
                throw new Exception("Error, please call Initalize first!");
            }

            Dictionary <string, object> state = new Dictionary <string, object>();

            state["ComObject"] = comObject;
            state["ComArg"]    = value;

            string cmd = "setattr(ComObject, '" + property + "', ComArg)";

            Scripting.EvalExpression(cmd, state);
        }
Example #10
0
        protected virtual void OnStarting()
        {
            if (!string.IsNullOrEmpty(onStart))
            {
                Dictionary <string, object> state = new Dictionary <string, object>();
                state["action"] = this;
                state["state"]  = this.parent;
                state["self"]   = this;

                Scripting.EvalExpression(onStart, state);
            }

            if (Starting != null)
            {
                Starting(this);
            }
        }
Example #11
0
        protected virtual void OnFinished()
        {
            if (!string.IsNullOrEmpty(onComplete))
            {
                Dictionary <string, object> state = new Dictionary <string, object>();
                state["action"] = this;
                state["state"]  = this.parent;
                state["self"]   = this;

                Scripting.EvalExpression(onComplete, state);
            }

            if (Finished != null)
            {
                Finished(this);
            }
        }
Example #12
0
        public override void SetValue(Variant value)
        {
            int size = (int)value;

            if (_expressionSet != null)
            {
                Dictionary <string, object> state = new Dictionary <string, object>();
                state["size"]  = size / 8;
                state["value"] = size / 8;
                state["self"]  = From;

                object newValue = Scripting.EvalExpression(_expressionSet, state);
                size = Convert.ToInt32(newValue);
            }

            From.DefaultValue = new Variant(size);
        }
Example #13
0
        public override void SetValue(Variant value)
        {
            int offset = (int)value;

            if (_expressionSet != null)
            {
                Dictionary <string, object> state = new Dictionary <string, object>();
                state["offset"] = offset;
                state["value"]  = offset;
                state["self"]   = this._parent;

                object newValue = Scripting.EvalExpression(_expressionGet, state);
                offset = Convert.ToInt32(newValue);
            }

            _from.DefaultValue = new Variant(offset);
        }
Example #14
0
        protected override Variant fixupImpl()
        {
            var    from       = elements["ref"];
            string expression = (string)args["expression"];

            byte[] data = from.Value.Value;

            Dictionary <string, object> state = new Dictionary <string, object>();

            state["self"] = this;
            state["ref"]  = from;
            state["data"] = data;
            try
            {
                object value = Scripting.EvalExpression(expression, state);

                if (value is string)
                {
                    string str      = value as string;
                    byte[] strbytes = new byte[str.Length];

                    for (int i = 0; i < strbytes.Length; ++i)
                    {
                        strbytes[i] = (byte)str[i];
                    }

                    return(new Variant(strbytes));
                }
                else if (value is int)
                {
                    return(new Variant(Convert.ToInt32(value)));
                }
                else
                {
                    throw new PeachException(
                              string.Format("ExpressionFixup expected a return value of string or int but got '{0}'", value.GetType().Name));
                }
            }
            catch (System.Exception ex)
            {
                throw new PeachException(
                          string.Format("ExpressionFixup expression threw an exception!\nExpression: {0}\n Exception: {1}", expression, ex.ToString()), ex);
            }
        }
Example #15
0
        public override Variant CalculateFromValue()
        {
            if (_isRecursing)
            {
                return(new Variant(0));
            }

            try
            {
                if (Of == null)
                {
                    logger.Error("Error, Of returned null");
                    return(null);
                }

                _isRecursing = true;

                // calculateOffset can throw PeachException during mutations
                // we will catch and return null;
                long offset = calculateOffset(From, Of) / 8;

                if (_expressionGet != null)
                {
                    Dictionary <string, object> state = new Dictionary <string, object>();
                    state["offset"] = offset;
                    state["value"]  = offset;
                    state["self"]   = this._parent;

                    object value = Scripting.EvalExpression(_expressionSet, state);
                    offset = Convert.ToInt32(value);
                }

                return(new Variant(offset));
            }
            catch (PeachException ex)
            {
                logger.Error(ex.Message);
                return(null);
            }
            finally
            {
                _isRecursing = false;
            }
        }
Example #16
0
        void addElements(DataElement de, BitStream data, Dictionary <DataElement, Position> positions, long offset)
        {
            Position pos;

            if (!positions.TryGetValue(de, out pos))
            {
                pos = new Position()
                {
                    begin = -offset, end = -offset
                }
            }
            ;

            OnEnterHandleNodeEvent(de, offset + pos.begin, data);

            var cont = de as DataElementContainer;

            if (cont != null)
            {
                foreach (var child in cont)
                {
                    addElements(child, data, positions, offset);
                }
            }

            OnExitHandleNodeEvent(de, offset + pos.end, data);
        }

        #endregion

        #region Handlers

        #region Top Level Handlers

        void handleRoot(DataElement element, BitStream data)
        {
            _sizedElements        = new Dictionary <DataElement, SizedPosition>();
            _sizeRelations        = new List <SizeRelation>();
            _elementsWithAnalyzer = new List <DataElement>();

            // We want at least 1 byte before we begin
            data.WantBytes(1);

            // Crack the model
            handleNode(element, data);

            // Handle any analyzers
            foreach (DataElement elem in _elementsWithAnalyzer)
            {
                OnAnalyzerEvent(elem, data);

                var positions = new Dictionary <DataElement, Position>();
                var parent    = elem.parent;

                try
                {
                    elem.analyzer.asDataElement(elem, positions);
                }
                catch (Exception ex)
                {
                    throw new CrackingFailure("Exception in analyzer on '" + elem.fullName + "': " + ex.Message, elem, data, ex);
                }

                var de  = parent[elem.name];
                var pos = _sizedElements[elem];
                positions[elem] = new Position()
                {
                    begin = 0, end = pos.end - pos.begin
                };
                addElements(de, data, positions, pos.begin);
            }
        }

        /// <summary>
        /// Called to crack a DataElement based on an input stream.  This method
        /// will hand cracking off to a more specific method after performing
        /// some common tasks.
        /// </summary>
        /// <param name="elem">DataElement to crack</param>
        /// <param name="data">Input stream to use for data</param>
        void handleNode(DataElement elem, BitStream data)
        {
            List <BitStream> oldStack = null;

            try
            {
                if (elem == null)
                {
                    throw new ArgumentNullException("elem");
                }
                if (data == null)
                {
                    throw new ArgumentNullException("data");
                }

                logger.Debug("------------------------------------");
                logger.Debug("{0} {1}", elem.debugName, data.Progress);

                var pos = handleNodeBegin(elem, data);

                if (elem.transformer != null)
                {
                    long startPos    = data.PositionBits;
                    var  sizedData   = elem.ReadSizedData(data, pos.size);
                    var  decodedData = elem.transformer.decode(sizedData);

                    // Make a new stack of data for the decoded data
                    oldStack   = _dataStack;
                    _dataStack = new List <BitStream>();
                    _dataStack.Add(decodedData);

                    // Use the size of the transformed data as the new size of the element
                    handleCrack(elem, decodedData, decodedData.LengthBits);

                    // Make sure the non-decoded data is at the right place
                    if (data == decodedData)
                    {
                        data.SeekBits(startPos + decodedData.LengthBits, System.IO.SeekOrigin.Begin);
                    }
                }
                else
                {
                    handleCrack(elem, data, pos.size);
                }

                if (elem.constraint != null)
                {
                    handleConstraint(elem, data);
                }

                if (elem.analyzer != null)
                {
                    _elementsWithAnalyzer.Add(elem);
                }

                handleNodeEnd(elem, data, pos);
            }
            catch (Exception e)
            {
                handleException(elem, data, e);
                throw;
            }
            finally
            {
                if (oldStack != null)
                {
                    _dataStack = oldStack;
                }
            }
        }

        void handlePlacelemt(DataElement element, BitStream data)
        {
            var fixups = new List <Tuple <Fixup, string, string> >();
            DataElementContainer oldParent = element.parent;

            // Ensure relations are resolved
            foreach (var relation in element.relations)
            {
                if (relation.Of != element && relation.From != element)
                {
                    throw new CrackingFailure("Error, unable to resolve Relations of/from to match current element.", element, data);
                }
            }

            // Locate relevant fixups
            DataElementContainer root = element.getRoot() as DataElementContainer;

            foreach (DataElement child in root.EnumerateAllElements())
            {
                if (child.fixup == null)
                {
                    continue;
                }

                foreach (var item in child.fixup.references)
                {
                    var refElem = child.find(item.Item2);
                    if (refElem == null)
                    {
                        throw new CrackingFailure("Error, unable to resolve Fixup reference to match current element.", element, data);
                    }

                    if (refElem == element)
                    {
                        fixups.Add(new Tuple <Fixup, string, string>(child.fixup, item.Item1, null));
                    }
                    else if (!refElem.isChildOf(element))
                    {
                        fixups.Add(new Tuple <Fixup, string, string>(child.fixup, item.Item1, refElem.fullName));
                    }
                }
            }

            // Update fixups
            foreach (var fixup in fixups)
            {
                if (fixup.Item3 != null)
                {
                    fixup.Item1.updateRef(fixup.Item2, fixup.Item3);
                }
            }


            string      debugName = element.debugName;
            DataElement newElem   = null;

            if (element.placement.after != null)
            {
                var after = element.find(element.placement.after);
                if (after == null)
                {
                    throw new CrackingFailure("Error, unable to resolve Placement on element '" + element.fullName +
                                              "' with 'after' == '" + element.placement.after + "'.", element, data);
                }
                newElem = element.MoveAfter(after);
            }
            else if (element.placement.before != null)
            {
                DataElement before = element.find(element.placement.before);
                if (before == null)
                {
                    throw new CrackingFailure("Error, unable to resolve Placement on element '" + element.fullName +
                                              "' with 'after' == '" + element.placement.after + "'.", element, data);
                }
                newElem = element.MoveBefore(before);
            }

            // Update fixups
            foreach (var fixup in fixups)
            {
                if (fixup.Item3 == null)
                {
                    fixup.Item1.updateRef(fixup.Item2, newElem.fullName);
                }
            }

            // Clear placement now that it has occured
            newElem.placement = null;

            logger.Debug("handlePlacement: {0} -> {1}", debugName, newElem.fullName);

            OnPlacementEvent(element, newElem, oldParent);
        }

        #endregion

        #region Helpers

        void handleOffsetRelation(DataElement element, BitStream data)
        {
            long?offset = getRelativeOffset(element, data, 0);

            if (!offset.HasValue)
            {
                return;
            }

            offset += data.PositionBits;

            if (offset > data.LengthBits)
            {
                data.WantBytes((offset.Value + 7 - data.LengthBits) / 8);
            }

            if (offset > data.LengthBits)
            {
                string msg = "{0} has offset of {1} bits but buffer only has {2} bits.".Fmt(
                    element.debugName, offset, data.LengthBits);
                throw new CrackingFailure(msg, element, data);
            }

            data.SeekBits(offset.Value, System.IO.SeekOrigin.Begin);
        }

        void handleException(DataElement elem, BitStream data, Exception e)
        {
            _sizedElements.Remove(elem);
            _sizeRelations.RemoveAll(r => r.Of == elem);

            CrackingFailure ex = e as CrackingFailure;

            if (ex != null)
            {
                logger.Debug("{0} failed to crack.", elem.debugName);
                if (!ex.logged)
                {
                    logger.Debug(ex.Message);
                }
                ex.logged = true;
            }
            else
            {
                logger.Debug("Exception occured: {0}", e.ToString());
            }

            OnExceptionHandleNodeEvent(elem, data.PositionBits, data, e);
        }

        void handleConstraint(DataElement element, BitStream data)
        {
            logger.Debug("Running constraint [" + element.constraint + "]");

            Dictionary <string, object> scope = new Dictionary <string, object>();

            scope["element"] = element;

            // Use DefaultValue for constraint, it is the actual cracked value.
            // InternalValue will have relations/fixups applied

            var iv = element.DefaultValue;

            if (iv == null)
            {
                scope["value"] = null;
                logger.Debug("Constraint, value=None.");
            }
            else if (iv.GetVariantType() == Variant.VariantType.ByteString || iv.GetVariantType() == Variant.VariantType.BitStream)
            {
                scope["value"] = (BitwiseStream)iv;
                logger.Debug("Constraint, value=byte array.");
            }
            else
            {
                scope["value"] = (string)iv;
                logger.Debug("Constraint, value=[" + (string)iv + "].");
            }

            object oReturn = Scripting.EvalExpression(element.constraint, scope);

            if (!((bool)oReturn))
            {
                throw new CrackingFailure("Constraint failed.", element, data);
            }
        }

        SizedPosition handleNodeBegin(DataElement elem, BitStream data)
        {
            handleOffsetRelation(elem, data);

            System.Diagnostics.Debug.Assert(!_sizedElements.ContainsKey(elem));

            long?size = getSize(elem, data);

            var pos = new SizedPosition();

            pos.begin = data.PositionBits + getDataOffset();
            pos.size  = size;

            _sizedElements.Add(elem, pos);

            // If this element does not have a size but has a size relation,
            // keep track of the relation for evaluation in the future
            if (!size.HasValue)
            {
                var rel = elem.relations.Of <SizeRelation>();
                _sizeRelations.AddRange(rel);
            }

            OnEnterHandleNodeEvent(elem, pos.begin, data);

            return(pos);
        }

        void handleNodeEnd(DataElement elem, BitStream data, Position pos)
        {
            // Completing this element might allow us to evaluate
            // outstanding size reation computations.

            for (int i = _sizeRelations.Count - 1; i >= 0; --i)
            {
                var rel = _sizeRelations[i];

                if (elem == rel.From)
                {
                    var  other = _sizedElements[rel.Of];
                    long size  = rel.GetValue();

                    if (other.size.HasValue)
                    {
                        logger.Debug("Size relation of {0} cracked again. Updating size from: {1} to: {2}",
                                     rel.Of.debugName, other.size, size);
                    }
                    else
                    {
                        logger.Debug("Size relation of {0} cracked. Updating size to: {1}",
                                     rel.Of.debugName, size);
                    }

                    other.size = size;
                    _sizeRelations.RemoveAt(i);
                }

                var cont = elem as DataElementContainer;
                if (cont != null && cont.isParentOf(rel.From))
                {
                    // If we have finished cracking the parent of the From half of
                    // an outstanding size relation, this means we never cracked
                    // the From element. This can happen when the From half is in
                    // a choice. Just stop tracking the incomplete relation and
                    // keep going.

                    _sizeRelations.RemoveAt(i);
                }
            }

            // Mark the end position of this element
            pos.end = data.PositionBits + getDataOffset();

            OnExitHandleNodeEvent(elem, pos.end, data);
        }

        void handleCrack(DataElement elem, BitStream data, long?size)
        {
            logger.Debug("Crack: {0} Size: {1}, {2}", elem.debugName,
                         size.HasValue ? size.ToString() : "<null>", data.Progress);

            elem.Crack(this, data, size);
        }

        #endregion

        #endregion

        #region Calculate Element Size

        long?getRelativeOffset(DataElement elem, BitStream data, long minOffset = 0)
        {
            var relations = elem.relations.Of <OffsetRelation>();

            if (!relations.Any())
            {
                return(null);
            }

            // Ensure we have cracked the from half of the relation
            var rel = relations.Where(HasCracked).FirstOrDefault();

            if (rel == null)
            {
                return(null);
            }

            // Offset is in bytes
            long offset = (long)rel.GetValue() * 8;

            if (rel.isRelativeOffset)
            {
                DataElement from = rel.From;

                if (rel.relativeTo != null)
                {
                    from = from.find(rel.relativeTo);
                }

                if (from == null)
                {
                    throw new CrackingFailure("Unable to locate 'relativeTo' element in relation attached to " +
                                              elem.debugName + "'.", elem, data);
                }

                // Get the position we are related to
                SizedPosition pos;
                if (!_sizedElements.TryGetValue(from, out pos))
                {
                    return(null);
                }

                // If relativeTo, offset is from beginning of relativeTo element
                // Otherwise, offset is after the From element
                offset += rel.relativeTo != null ? pos.begin : pos.end;
            }

            // Adjust offset to be relative to the current BitStream
            offset -= getDataOffset();

            // Ensure the offset is not before our current position
            if (offset < data.PositionBits)
            {
                string msg = "{0} has offset of {1} bits but already read {2} bits.".Fmt(
                    elem.debugName, offset, data.PositionBits);
                throw new CrackingFailure(msg, elem, data);
            }

            // Make offset relative to current position
            offset -= data.PositionBits;

            // Ensure the offset satisfies the minimum
            if (offset < minOffset)
            {
                string msg = "{0} has offset of {1} bits but must be at least {2} bits.".Fmt(
                    elem.debugName, offset, minOffset);
                throw new CrackingFailure(msg, elem, data);
            }

            return(offset);
        }

        /// <summary>
        /// Searches data for the first occurance of token starting at offset.
        /// </summary>
        /// <param name="data">BitStream to search in.</param>
        /// <param name="token">BitStream to search for.</param>
        /// <param name="offset">How many bits after the current position of data to start searching.</param>
        /// <returns>The location of the token in data from the current position or null.</returns>
        long?findToken(BitStream data, BitwiseStream token, long offset)
        {
            while (true)
            {
                long start = data.PositionBits;
                long end   = data.IndexOf(token, start + offset);

                if (end >= 0)
                {
                    return(end - start);
                }

                long dataLen = data.Length;
                data.WantBytes(token.Length);

                if (dataLen == data.Length)
                {
                    return(null);
                }
            }
        }

        bool?scanArray(Dom.Array array, ref long pos, List <Mark> tokens, Until until)
        {
            logger.Debug("scanArray: {0}", array.debugName);

            int  tokenCount = tokens.Count;
            long arrayPos   = 0;
            var  ret        = scan(array.origionalElement, ref arrayPos, tokens, null, until);

            for (int i = tokenCount; i < tokens.Count; ++i)
            {
                tokens[i].Optional  = array.Count >= array.minOccurs;
                tokens[i].Position += pos;
            }

            if (ret.HasValue && ret.Value)
            {
                if (until == Until.FirstSized)
                {
                    ret = false;
                }

                var relations = array.relations.Of <CountRelation>();
                if (relations.Any())
                {
                    var rel = relations.Where(HasCracked).FirstOrDefault();
                    if (rel != null)
                    {
                        arrayPos *= rel.GetValue();
                        pos      += arrayPos;
                        logger.Debug("scanArray: {0} -> Count Relation: {1}, Size: {2}",
                                     array.debugName, rel.GetValue(), arrayPos);
                        return(ret);
                    }
                    else
                    {
                        logger.Debug("scanArray: {0} -> Count Relation: ???", array.debugName);
                        return(null);
                    }
                }
                else if (array.minOccurs == 1 && array.maxOccurs == 1)
                {
                    arrayPos *= array.occurs;
                    pos      += arrayPos;
                    logger.Debug("scanArray: {0} -> Occurs: {1}, Size: {2}",
                                 array.debugName, array.occurs, arrayPos);
                    return(ret);
                }
                else
                {
                    // If the count is unknown, treat the array unsized
                    ret = null;

                    // If no tokens were found in the array, we are done
                    if (tokenCount == tokens.Count)
                    {
                        logger.Debug("scanArray: {0} -> Count Unknown", array.debugName);
                        return(ret);
                    }
                }
            }

            // If we are looking for the first sized element, try cracking our first element
            if (until == Until.FirstSized)
            {
                logger.Debug("scanArray: {0} -> FirstSized", array.debugName);
                return(false);
            }

            if (tokenCount == tokens.Count)
            {
                logger.Debug("scanArray: {0} -> No Tokens", array.debugName);
                //ret.HasValue ? "Deterministic" : "Unsized");
                return(false);
            }

            // If we have tokens, keep scanning thru the dom.
            logger.Debug("scanArray: {0} -> Tokens", array.debugName);
            return(true);
        }
Example #17
0
        public void Run(RunContext context)
        {
            logger.Trace("Run({0}): {1}", name, type);

            if (when != null)
            {
                Dictionary <string, object> state = new Dictionary <string, object>();
                state["context"]    = context;
                state["Context"]    = context;
                state["action"]     = this;
                state["Action"]     = this;
                state["state"]      = this.parent;
                state["State"]      = this.parent;
                state["StateModel"] = this.parent.parent;
                state["Test"]       = this.parent.parent.parent;
                state["self"]       = this;

                object value = Scripting.EvalExpression(when, state);
                if (!(value is bool))
                {
                    logger.Debug("Run: action '{0}' when return is not boolean, returned: {1}", name, value);
                    return;
                }

                if (!(bool)value)
                {
                    logger.Debug("Run: action '{0}' when returned false", name);
                    return;
                }
            }

            try
            {
                Publisher publisher = null;
                if (this.publisher != null && this.publisher != "Peach.Agent")
                {
                    if (!context.test.publishers.ContainsKey(this.publisher))
                    {
                        logger.Debug("Run: Publisher '" + this.publisher + "' not found!");
                        throw new PeachException("Error, Action '" + name + "' publisher value '" + this.publisher + "' was not found!");
                    }

                    publisher = context.test.publishers[this.publisher];
                }
                else
                {
                    publisher = context.test.publishers[0];
                }

                if (context.controlIteration && context.controlRecordingIteration)
                {
                    logger.Debug("Run: Adding action to controlRecordingActionsExecuted");
                    context.controlRecordingActionsExecuted.Add(this);
                }
                else if (context.controlIteration)
                {
                    logger.Debug("Run: Adding action to controlActionsExecuted");
                    context.controlActionsExecuted.Add(this);
                }

                started  = true;
                finished = false;
                error    = false;

                OnStarting();

                logger.Debug("ActionType.{0}", type.ToString());

                switch (type)
                {
                case ActionType.Start:
                    publisher.start();
                    break;

                case ActionType.Stop:
                    publisher.close();
                    publisher.stop();
                    break;

                case ActionType.Open:
                case ActionType.Connect:
                    publisher.start();
                    publisher.open();
                    break;

                case ActionType.Close:
                    publisher.start();
                    publisher.close();
                    break;

                case ActionType.Accept:
                    publisher.start();
                    publisher.open();
                    publisher.accept();
                    break;

                case ActionType.Input:
                    publisher.start();
                    publisher.open();
                    publisher.input();
                    handleInput(publisher);
                    parent.parent.dataActions.Add(this);
                    break;

                case ActionType.Output:
                    publisher.start();
                    if (publisher is FilePublisher)
                    {
                        if (context.config.outputFilePath != null)
                        {
                            FilePublisher filePublisher = (FilePublisher)publisher;
                            filePublisher.FileName = context.config.outputFilePath;
                        }
                        if (context.config.inputFilePath != null)
                        {
                            if (File.Exists(context.config.inputFilePath))
                            {
                                fileLengthBytes = (int)new FileInfo(context.config.inputFilePath).Length;
                            }
                        }
                    }
                    publisher.open();
                    handleOutput(publisher);
                    parent.parent.dataActions.Add(this);
                    break;

                case ActionType.Call:
                    publisher.start();
                    handleCall(publisher, context);
                    parent.parent.dataActions.Add(this);
                    break;

                case ActionType.GetProperty:
                    publisher.start();
                    handleGetProperty(publisher);
                    parent.parent.dataActions.Add(this);
                    break;

                case ActionType.SetProperty:
                    publisher.start();
                    handleSetProperty(publisher);
                    parent.parent.dataActions.Add(this);
                    break;

                case ActionType.ChangeState:
                    handleChangeState();
                    break;

                case ActionType.Slurp:
                    handleSlurp(context);
                    break;

                default:
                    throw new ApplicationException("Error, Action.Run fell into unknown Action type handler!");
                }

                finished = true;
            }
            catch
            {
                error    = true;
                finished = true;
                throw;
            }
            finally
            {
                OnFinished();
            }
        }
Example #18
0
        public void Run(RunContext context)
        {
            logger.Trace("Run({0}): {1}", name, GetType().Name);

            // Setup scope for any scripting expressions
            scope["context"]    = context;
            scope["Context"]    = context;
            scope["action"]     = this;
            scope["Action"]     = this;
            scope["state"]      = parent;
            scope["State"]      = parent;
            scope["StateModel"] = parent.parent;
            scope["stateModel"] = parent.parent;
            scope["Test"]       = parent.parent.parent;
            scope["test"]       = parent.parent.parent;
            scope["self"]       = this;

            if (when != null)
            {
                object value = Scripting.EvalExpression(when, scope);
                if (!(value is bool))
                {
                    logger.Debug("Run: action '{0}' when return is not boolean, returned: {1}", name, value);
                    return;
                }

                if (!(bool)value)
                {
                    logger.Debug("Run: action '{0}' when returned false", name);
                    return;
                }
            }

            try
            {
                Publisher publisher = null;
                if (this.publisher != null && this.publisher != "Peach.Agent")
                {
                    if (!context.test.publishers.ContainsKey(this.publisher))
                    {
                        logger.Debug("Run: Publisher '" + this.publisher + "' not found!");
                        throw new PeachException("Error, Action '" + name + "' couldn't find publisher named '" + this.publisher + "'.");
                    }

                    publisher = context.test.publishers[this.publisher];
                }
                else
                {
                    publisher = context.test.publishers[0];
                }

                if (context.controlIteration && context.controlRecordingIteration)
                {
                    logger.Debug("Run: Adding action to controlRecordingActionsExecuted");
                    context.controlRecordingActionsExecuted.Add(this);
                }
                else if (context.controlIteration)
                {
                    logger.Debug("Run: Adding action to controlActionsExecuted");
                    context.controlActionsExecuted.Add(this);
                }

                started  = true;
                finished = false;
                error    = false;

                OnStarting();

                logger.Debug("ActionType.{0}", GetType().Name.ToString());

                RunScript(onStart);

                // Save output data
                foreach (var item in outputData)
                {
                    parent.parent.SaveData(item.outputName, item.dataModel.Value);
                }

                OnRun(publisher, context);

                // Save input data
                foreach (var item in inputData)
                {
                    parent.parent.SaveData(item.inputName, item.dataModel.Value);
                }

                RunScript(onComplete);

                finished = true;
            }
            catch (ActionChangeStateException)
            {
                // this is not an error
                throw;
            }
            catch
            {
                error = true;
                throw;
            }
            finally
            {
                finished = true;
                OnFinished();
            }
        }