Beispiel #1
0
        private void GetArrayTokens(List <Token <ModelTokenType> > tokens, ICycleDetector detector, IEnumerable value)
        {
            DataName    typeName   = this.GetTypeName(value);
            IEnumerator enumerator = value.GetEnumerator();

            if (enumerator is IEnumerator <KeyValuePair <string, object> > )
            {
                this.GetObjectTokens(tokens, detector, typeName, (IEnumerator <KeyValuePair <string, object> >)enumerator);
                return;
            }

            if (enumerator is IDictionaryEnumerator)
            {
                this.GetObjectTokens(tokens, detector, typeName, (IDictionaryEnumerator)enumerator);
                return;
            }

            tokens.Add(ModelGrammar.TokenArrayBegin(typeName));

            while (enumerator.MoveNext())
            {
                this.GetTokens(tokens, detector, enumerator.Current);
            }

            tokens.Add(ModelGrammar.TokenArrayEnd);
        }
        public void Finds_Repeated_Number(Type detectorType)
        {
            ICycleDetector target = Activator.CreateInstance(detectorType) as ICycleDetector;

            int actual = target.Detect(this.onlyOneDuplicateNumber);

            Assert.AreEqual(3, actual);
        }
Beispiel #3
0
        private void GetObjectTokens(List <Token <ModelTokenType> > tokens, ICycleDetector detector, DataName typeName, IDictionaryEnumerator enumerator)
        {
            tokens.Add(ModelGrammar.TokenObjectBegin(typeName));

            while (enumerator.MoveNext())
            {
                tokens.Add(ModelGrammar.TokenProperty(enumerator.Key));
                this.GetTokens(tokens, detector, enumerator.Value);
            }

            tokens.Add(ModelGrammar.TokenObjectEnd);
        }
Beispiel #4
0
        private void GetObjectTokens(List <Token <ModelTokenType> > tokens, ICycleDetector detector, DataName typeName, IEnumerator <KeyValuePair <string, object> > enumerator)
        {
            tokens.Add(ModelGrammar.TokenObjectBegin(typeName));

            while (enumerator.MoveNext())
            {
                KeyValuePair <string, object> pair = enumerator.Current;
                tokens.Add(ModelGrammar.TokenProperty(pair.Key));
                this.GetTokens(tokens, detector, pair.Value);
            }

            tokens.Add(ModelGrammar.TokenObjectEnd);
        }
Beispiel #5
0
        private void GetObjectTokens(List <Token <ModelTokenType> > tokens, ICycleDetector detector, Type type, System.Dynamic.DynamicObject value)
        {
            DataName typeName = this.GetTypeName(value);

            tokens.Add(ModelGrammar.TokenObjectBegin(typeName));

            foreach (var memberName in value.GetDynamicMemberNames())
            {
                object propertyValue;
                if (!value.TryGetMember(new DynamicGetter(memberName), out propertyValue))
                {
                    continue;
                }

                tokens.Add(ModelGrammar.TokenProperty(memberName));
                this.GetTokens(tokens, detector, propertyValue);
            }

            tokens.Add(ModelGrammar.TokenObjectEnd);
        }
Beispiel #6
0
        private void GetObjectTokens(List <Token <ModelTokenType> > tokens, ICycleDetector detector, Type type, object value)
        {
            DataName typeName = this.GetTypeName(value);

            tokens.Add(ModelGrammar.TokenObjectBegin(typeName));

            IDictionary <string, MemberMap> maps = this.Settings.Resolver.LoadMaps(type);

            if (maps == null)
            {
                // TODO: verify no other valid situations here
                tokens.Add(ModelGrammar.TokenObjectEnd);
                return;
            }

            // allow the resolver to optionally sort the members
            IEnumerable <MemberMap> members = this.Settings.Resolver.SortMembers(maps.Values);

            foreach (var map in members)
            {
                if (map.IsAlternate ||
                    map.Getter == null)
                {
                    continue;
                }

                object propertyValue = map.Getter(value);
                if (map.IsIgnored != null &&
                    map.IsIgnored(value, propertyValue))
                {
                    continue;
                }

                tokens.Add(ModelGrammar.TokenProperty(map.DataName));
                this.GetTokens(tokens, detector, propertyValue);
            }

            tokens.Add(ModelGrammar.TokenObjectEnd);
        }
Beispiel #7
0
 public Graph(ICycleDetector <T> cycleDetector)
 {
     _cycleDetector = cycleDetector;
 }
Beispiel #8
0
        private void GetTokens(List <Token <ModelTokenType> > tokens, ICycleDetector detector, object value)
        {
            if (value == null)
            {
                tokens.Add(ModelGrammar.TokenNull);
                return;
            }

            // test for cycles
            if (detector.Add(value))
            {
                switch (this.Settings.GraphCycles)
                {
                case GraphCycleType.Reference:
                {
                    // no need to remove value as was duplicate reference
                    throw new GraphCycleException(GraphCycleType.Reference, "Graph cycle detected: repeated references");
                }

                case GraphCycleType.MaxDepth:
                {
                    throw new GraphCycleException(GraphCycleType.MaxDepth, "Graph cycle potentially detected: maximum depth exceeded");
                }

                default:
                case GraphCycleType.Ignore:
                {
                    // no need to remove value as was duplicate reference
                    // replace cycle with null
                    tokens.Add(ModelGrammar.TokenNull);
                    return;
                }
                }
            }

            try
            {
                foreach (var filter in this.Filters)
                {
                    IEnumerable <Token <ModelTokenType> > filterResult;
                    if (filter.TryWrite(this.Settings, value, out filterResult))
                    {
                        // found a successful match
                        tokens.AddRange(filterResult);
                        return;
                    }
                }

                Type type = value.GetType();

                // must test enumerations before other value types
                if (type.IsEnum)
                {
                    tokens.Add(ModelGrammar.TokenPrimitive((Enum)value));
                    return;
                }

                // Type.GetTypeCode() allows us to more efficiently switch type
                switch (Type.GetTypeCode(type))
                {
                case TypeCode.Boolean:
                {
                    tokens.Add(true.Equals(value) ? ModelGrammar.TokenTrue : ModelGrammar.TokenFalse);
                    return;
                }

                case TypeCode.Byte:
                case TypeCode.Decimal:
                case TypeCode.Int16:
                case TypeCode.Int32:
                case TypeCode.Int64:
                case TypeCode.SByte:
                case TypeCode.UInt16:
                case TypeCode.UInt32:
                case TypeCode.UInt64:
                {
                    tokens.Add(ModelGrammar.TokenPrimitive((ValueType)value));
                    return;
                }

                case TypeCode.Double:
                {
                    double doubleVal = (double)value;

                    if (Double.IsNaN(doubleVal))
                    {
                        tokens.Add(ModelGrammar.TokenNaN);
                    }
                    else if (Double.IsPositiveInfinity(doubleVal))
                    {
                        tokens.Add(ModelGrammar.TokenPositiveInfinity);
                    }
                    else if (Double.IsNegativeInfinity(doubleVal))
                    {
                        tokens.Add(ModelGrammar.TokenNegativeInfinity);
                    }
                    else
                    {
                        tokens.Add(ModelGrammar.TokenPrimitive(doubleVal));
                    }
                    return;
                }

                case TypeCode.Single:
                {
                    float floatVal = (float)value;

                    if (Single.IsNaN(floatVal))
                    {
                        // use the Double equivalent
                        tokens.Add(ModelGrammar.TokenNaN);
                    }
                    else if (Single.IsPositiveInfinity(floatVal))
                    {
                        // use the Double equivalent
                        tokens.Add(ModelGrammar.TokenPositiveInfinity);
                    }
                    else if (Single.IsNegativeInfinity(floatVal))
                    {
                        // use the Double equivalent
                        tokens.Add(ModelGrammar.TokenNegativeInfinity);
                    }
                    else
                    {
                        tokens.Add(ModelGrammar.TokenPrimitive(floatVal));
                    }
                    return;
                }

                case TypeCode.Char:
                case TypeCode.DateTime:
                case TypeCode.String:
                {
                    tokens.Add(ModelGrammar.TokenPrimitive(value));
                    return;
                }

                case TypeCode.DBNull:
                case TypeCode.Empty:
                {
                    tokens.Add(ModelGrammar.TokenNull);
                    return;
                }
                }

                if (value is IEnumerable)
                {
                    this.GetArrayTokens(tokens, detector, (IEnumerable)value);
                    return;
                }

                if (value is Guid || value is Uri || value is Version)
                {
                    tokens.Add(ModelGrammar.TokenPrimitive(value));
                    return;
                }

                if (value is TimeSpan)
                {
                    tokens.Add(ModelGrammar.TokenPrimitive((TimeSpan)value));
                    return;
                }

#if NET40 && !WINDOWS_PHONE
                if (value is System.Dynamic.DynamicObject)
                {
                    // TODO: expand to all IDynamicMetaObjectProvider?
                    this.GetObjectTokens(tokens, detector, type, (System.Dynamic.DynamicObject)value);
                    return;
                }
#endif

                // all other structs and classes
                this.GetObjectTokens(tokens, detector, type, value);
            }
            finally
            {
                detector.Remove(value);
            }
        }
Beispiel #9
0
            /// <summary>
            /// Waits until evaluation gets cancelled or a value is set
            /// </summary>
            public void Wait(ICycleDetector cycleDetector = null)
            {
                lock (this)
                {
                    if (m_result != EvaluationStatus.None)
                    {
                        return;
                    }

                    m_eventWaiters++;
                    if (m_event == null)
                    {
                        m_event = new ManualResetEvent(false);
                    }
                }

                if (cycleDetector == null)
                {
                    m_event.WaitOne();
                }
                else
                {
                    // wait for evaluation in separate thread to finish
                    m_event.WaitOne(m_startupDelay);

                    // at first, wait for a reasonable amount of time without actually starting up cycle detector
                    bool hasResult;
                    lock (this)
                    {
                        hasResult = m_result != EvaluationStatus.None;
                    }

                    if (!hasResult)
                    {
                        // after the first delay, evaluation is still neither canceled nor finished; let's make sure the cycle detector is actually started up
                        cycleDetector.EnsureStarted();
                        m_event.WaitOne(m_increasePriorityDelay);

                        // second, wait for a reasonable amount of time without tinkering with priorities
                        lock (this)
                        {
                            hasResult = m_result != EvaluationStatus.None;
                        }

                        if (!hasResult)
                        {
                            // after the second delay, evaluation is still neither canceled nor finished; let's raise priority of cycle detector while we keep waiting
                            using (cycleDetector.IncreasePriority())
                            {
                                m_event.WaitOne();

                                // third, just keep waiting until signaled, because of cancellation of because evaluation finishes
                            }
                        }
                    }
                }

                lock (this)
                {
                    Contract.Assume(m_result != EvaluationStatus.None);
                    if (--m_eventWaiters == 0)
                    {
                        m_event.Dispose();
                        m_event = null;
                    }
                }
            }