示例#1
0
        /// <summary>Updates active edge and current position</summary>
        private void UpdateActiveEdgeAndCurrentPosition()
        {
            if (_nextSuffixOffset > _currentOffset)
            {
                // all pending proper sub-suffixes have been processed
                // start from the root
                _currentOffset        = _nextSuffixOffset;
                _branchNodeIndex      = RootNodeIndex;
                _activeEdgeIndex      = InvalidNodeIndex;
                _activeLength         = 0;
                _pendingLinkIndexFrom = InvalidNodeIndex;
                return;
            }
            // try to follow the link if it is present
            _branchNodeIndex = _nodeLinks.Value[_branchNodeIndex];
            if (_branchNodeIndex == InvalidNodeIndex)
            {
                _activeLength    = _currentOffset - _nextSuffixOffset;
                _branchNodeIndex = RootNodeIndex;
            }
            _activeEdgeIndex = InvalidNodeIndex;
            if (_activeLength == 0)
            {
                // we are already at a correct node
                return;
            }
            // go down over the tree
            var branchNode = GetNode(_branchNodeIndex);

            for (;;)
            {
                DebugCode.AssertState(!branchNode.IsLeaf, "Invalid active state");
                var index    = _currentOffset - _activeLength;
                var children = branchNode.Children;
                DebugCode.AssertState(children != null, nameof(children) + " != null");
                var childIndex = children.LowerBound(InternalData[index], EdgeComparer);
                DebugCode.AssertState(childIndex != children.Count, "Invalid active state");
                var edgeIndex = children[childIndex];
                var edgeNode  = GetNode(edgeIndex);
                DebugCode.AssertState(InternalData[edgeNode.Begin] == InternalData[index], "Invalid active state");
                var edgeLength = edgeNode.Length;
                if (edgeLength <= _activeLength)
                {
                    _activeLength   -= edgeLength;
                    _branchNodeIndex = edgeIndex;
                    if (_activeLength == 0)
                    {
                        return;
                    }
                    branchNode = edgeNode;
                }
                else
                {
                    _activeEdgeIndex = childIndex;
                    return;
                }
            }
        }
示例#2
0
        internal RangeIntersection(Range <T> intersectionRange, [NotNull] Range <T>[] ranges)
        {
            // TODO: bugif.
            DebugCode.AssertState(
                ranges.All(r => r.Contains(intersectionRange)),
                "Ranges should contain groupingRange.");

            IntersectionRange = intersectionRange;
            _ranges           = ranges.AsReadOnly();
        }
示例#3
0
        /// <summary>Locates the source string index by the suffix end</summary>
        /// <param name="end">The suffix end</param>
        /// <returns>The source string index</returns>
        private int GetSourceIndexByEnd(int end)
        {
            // CSC bug?
            // ReSharper disable once RedundantTypeArgumentsOfMethod
            var index = StringLocations.LowerBound(end, _stringLocationByEndComparer);

            DebugCode.AssertState(
                index < StringLocations.Count && StringLocations[index].Length == end,
                "Invalid source index computed. Check logic");
            return(index);
        }
示例#4
0
        public static Type GetDefaultMappingFromEnumType([NotNull] MappingSchema mappingSchema, [NotNull] Type enumType)
        {
            var type = enumType.ToNullableUnderlying();

            if (!type.GetIsEnum())
            {
                return(null);
            }

            var fields =
                (
                    from f in type.GetFields()
                    where (f.Attributes & _enumField) == _enumField
                    let attrs = mappingSchema.GetAttributes <MapValueAttribute>(f, a => a.Configuration)
                                select
                                (
                        from a in attrs
                        where a.Configuration == attrs[0].Configuration
                        orderby !a.IsDefault
                        select a
                                ).ToList()
                ).ToList();

            Type defaultType = null;

            if (fields.All(attrs => attrs.Count != 0))
            {
                var attr = fields.FirstOrDefault(attrs => attrs[0].Value != null);

                if (attr != null)
                {
                    DebugCode.AssertState(attr[0].Value != null, "attr[0].Value != null");
                    var valueType = attr[0].Value.GetType();

                    if (fields.All(attrs => attrs[0].Value == null || attrs[0].Value.GetType() == valueType))
                    {
                        defaultType = valueType;
                    }
                }
            }

            if (defaultType == null)
            {
                defaultType = Enum.GetUnderlyingType(type);
            }

            if (enumType.IsNullable() && !defaultType.GetIsClass() && !defaultType.IsNullable())
            {
                defaultType = typeof(Nullable <>).MakeGenericType(defaultType);
            }

            return(defaultType);
        }
示例#5
0
            void WriteElementType(StringBuilder sb, Type t)
            {
                DebugCode.AssertState(t.IsArray || t.IsPointer || t.IsByRef, "Invalid type");

                Write(sb, t.GetElementType());

                if (t.IsArray)
                {
                    sb.Append('[');
                    sb.Append(',', t.GetArrayRank() - 1);
                    sb.Append(']');
                }
                else
                {
                    sb.Append(t.IsPointer ? '*' : '&');
                }
            }
示例#6
0
        /// <summary>
        /// Returns custom attributes applied to provided type member.
        /// </summary>
        /// <param name="memberInfo">Type member.</param>
        /// <param name="inherit"><b>true</b> to search this member's inheritance chain to find the attributes; otherwise, <b>false</b>.</param>
        /// <typeparam name="T">The type of attribute to search for. Only attributes that are assignable to this member are returned.</typeparam>
        /// <returns>Array of custom attributes.</returns>
        public T[] GetAttributes <T>(MemberInfo memberInfo, bool inherit = true)
            where T : Attribute
        {
            var type = memberInfo.DeclaringType;

            DebugCode.AssertState(type != null, "type != null");
            DebugCode.AssertState(type.FullName != null, "type.FullName != null");
            if (_types.TryGetValue(type.FullName, out var t) || _types.TryGetValue(type.Name, out t))
            {
                if (t.Members.TryGetValue(memberInfo.Name, out var m))
                {
                    return
                        (m
                         .GetAttribute(typeof(T))
                         .Select(a => (T)a.MakeAttribute(typeof(T)))
                         .ToArray());
                }
            }

            return(Array <T> .Empty);
        }
示例#7
0
            void WriteGenericArguments(StringBuilder sb, Type t)
            {
                DebugCode.AssertState(t.GetIsGenericType() && !t.GetIsGenericTypeDefinition(), "Invalid type");

                sb.Append('[');

                var arguments = t.GetGenericArguments();

                for (var i = 0; i < arguments.Length; i++)
                {
                    if (i != 0)
                    {
                        sb.Append(',');
                    }

                    sb.Append('[');
                    WriteFull(sb, arguments[i]);
                    sb.Append(']');
                }

                sb.Append(']');
            }
示例#8
0
        public static string GetShortAssemblyQualifiedName([NotNull] this Type type)
        {
            Code.NotNull(type, nameof(type));

            void WriteAssemblyName(StringBuilder sb, Type t)
            {
                sb.Append(", ");

                var index            = -1;
                var assemblyFullName = t.Assembly.FullName;

                while (true)
                {
                    index = assemblyFullName.IndexOf(',', index + 1);
                    DebugCode.BugIf(index == 0, "Invalid assembly name");

                    if (index < 0)
                    {
                        sb.Append(assemblyFullName);
                        return;
                    }

                    if (assemblyFullName[index - 1] != '\\')
                    {
                        sb.Append(assemblyFullName, 0, index);
                        return;
                    }
                }
            }

            void WriteGenericArguments(StringBuilder sb, Type t)
            {
                DebugCode.AssertState(t.IsGenericType && !t.IsGenericTypeDefinition, "Invalid type");

                sb.Append('[');

                var arguments = t.GetGenericArguments();

                for (var i = 0; i < arguments.Length; i++)
                {
                    if (i != 0)
                    {
                        sb.Append(',');
                    }

                    sb.Append('[');
                    WriteFull(sb, arguments[i]);
                    sb.Append(']');
                }

                sb.Append(']');
            }

            void WriteElementType(StringBuilder sb, Type t)
            {
                DebugCode.AssertState(t.IsArray || t.IsPointer || t.IsByRef, "Invalid type");

                Write(sb, t.GetElementType());

                if (t.IsArray)
                {
                    sb.Append('[');
                    sb.Append(',', t.GetArrayRank() - 1);
                    sb.Append(']');
                }
                else
                {
                    sb.Append(t.IsPointer ? '*' : '&');
                }
            }

            void WriteType(StringBuilder sb, Type t)
            {
                if (t.DeclaringType != null)
                {
                    WriteType(sb, t.DeclaringType);
                    sb.Append('+');
                }

                sb.Append(t.Name);
            }

            void Write(StringBuilder sb, Type t)
            {
                if (t.IsGenericType && !t.IsGenericTypeDefinition)
                {
                    WriteType(sb, t);
                    WriteGenericArguments(sb, t);
                }
                else if (t.IsArray || t.IsPointer || t.IsByRef)
                {
                    WriteElementType(sb, t);
                }
                else
                {
                    WriteType(sb, t);
                }
            }

            void WriteFull(StringBuilder sb, Type t)
            {
                if (t.Namespace.NotNullNorEmpty())
                {
                    sb.Append(t.Namespace);
                    sb.Append('.');
                }

                Write(sb, t);
                WriteAssemblyName(sb, t);
            }

            var builder = new StringBuilder();

            WriteFull(builder, type);
            return(builder.ToString());
        }
示例#9
0
        /// <summary>Finds the next branching point</summary>
        private void FindBranchingPoint()
        {
            var  branchNode = GetNode(_branchNodeIndex);
            var  children   = branchNode.Children;
            int  childNodeIndex;
            Node activeEdge;

            if (_activeEdgeIndex != InvalidNodeIndex)
            {
                childNodeIndex = children[_activeEdgeIndex];
                activeEdge     = GetNode(childNodeIndex);
            }
            else
            {
                childNodeIndex = InvalidNodeIndex;
                activeEdge     = default(Node);
            }
            for (;;)
            {
                if (_activeEdgeIndex == InvalidNodeIndex)
                {
                    DebugCode.AssertState(activeLength_ == 0, "Invalid active state");
                    if (_currentOffset == _end)
                    {
                        return;
                    }
                    if (branchNode.IsLeaf)
                    {
                        // a new branch
                        return;
                    }
                    var c          = InternalData[_currentOffset];
                    var childIndex = children.LowerBound(c, EdgeComparer);
                    if (childIndex == children.Count)
                    {
                        // a new branch
                        return;
                    }
                    childNodeIndex = children[childIndex];
                    var edgeNode = GetNode(childNodeIndex);
                    if (InternalData[edgeNode.Begin] != c)
                    {
                        // a new branch
                        return;
                    }
                    activeLength_    = 1;
                    _activeEdgeIndex = childIndex;
                    activeEdge       = edgeNode;
                    ++_currentOffset;
                }
                var edgeOffset = activeEdge.Begin + activeLength_;
                var edgeEnd    = activeEdge.End;
                for (;;)
                {
                    if (edgeOffset == edgeEnd)
                    {
                        // end of the current edge reached
                        _branchNodeIndex = childNodeIndex;
                        branchNode       = GetNode(_branchNodeIndex);
                        children         = branchNode.Children;
                        _activeEdgeIndex = InvalidNodeIndex;
                        activeEdge       = default(Node);
                        activeLength_    = 0;
                        break;
                    }
                    if (_currentOffset == _end)
                    {
                        return;
                    }
                    if (InternalData[edgeOffset] != InternalData[_currentOffset])
                    {
                        return;
                    }
                    ++activeLength_;
                    ++_currentOffset;
                    ++edgeOffset;
                }
            }
        }
示例#10
0
        /// <summary>Inserts a new suffix at the current position</summary>
        private void InsertSuffix()
        {
            Node insertionNode;
            int  insertionNodeIndex;
            var  branchNode = GetNode(_branchNodeIndex);

            if (_activeEdgeIndex != InvalidNodeIndex)
            {
                var branchChildren = branchNode.Children;
                var edgeNodeIndex  = branchChildren[_activeEdgeIndex];
                // need to create a new internal node
                var edgeNode = GetNode(edgeNodeIndex);
                DebugCode.AssertState(activeLength_ < edgeNode.Length, "Invalid active state");
                var newEdgeNode = new Node(edgeNode.Begin, edgeNode.Begin + activeLength_, false
                                           , new List <int> {
                    edgeNodeIndex
                });
                var newEdgeNodeIndex = AddNode(newEdgeNode);
                var updatedEdgeNode  = new Node(newEdgeNode.End, edgeNode.End, edgeNode.IsTerminal
                                                , edgeNode.Children);
                UpdateNode(edgeNodeIndex, updatedEdgeNode);
                branchChildren[_activeEdgeIndex] = newEdgeNodeIndex;
                insertionNode      = newEdgeNode;
                insertionNodeIndex = newEdgeNodeIndex;
            }
            else
            {
                DebugCode.AssertState(activeLength_ == 0, "Invalid active state");
                insertionNode      = branchNode;
                insertionNodeIndex = _branchNodeIndex;
            }
            // insert a new child edge
            var children = insertionNode.Children;
            int childNodeIndex;

            if (children == null)
            {
                children = new List <int>();
                var insertionNodeEnd = insertionNode.End;
                var updatedNode      = new Node(insertionNode.Begin, insertionNodeEnd, false, children);
                if (insertionNode.IsTerminal)
                {
                    // Do a split. New children: an empty terminal node and a new suffix node (will be added later)
                    var newTerminal      = new Node(insertionNodeEnd, insertionNodeEnd, true);
                    var newTerminalIndex = AddNode(newTerminal);
                    children.Add(newTerminalIndex);
                }
                UpdateNode(insertionNodeIndex, updatedNode);
                // insertionNode = updatedNode not needed since insertionNode value is not used later
                childNodeIndex = children.Count;
            }
            else
            {
                childNodeIndex = _currentOffset == _end
                                        ? 0 // empty nodes always at the beginning
                                        : children.LowerBound(InternalData[_currentOffset], EdgeComparer);
            }
            // now we have a non-empty children and an insertion index
            // just do an insert
            var newNode  = new Node(_currentOffset, _end, true);
            var newIndex = AddNode(newNode);

            children.Insert(childNodeIndex, newIndex);
            // create a link if needed
            if (LinkPending)
            {
                CreatePendingLink(insertionNodeIndex);
            }
            // and mask a branching node as link pending if it is not the root
            if (insertionNodeIndex != RootNodeIndex)
            {
                _pendingLinkIndexFrom = insertionNodeIndex;
            }
        }
示例#11
0
 /// <summary>Creates a pending link</summary>
 /// <param name="toNodeIndex">The node to link to</param>
 private void CreatePendingLink(int toNodeIndex)
 {
     DebugCode.AssertState(LinkPending, "Pending link should be present");
     _nodeLinks.Value[_pendingLinkIndexFrom] = toNodeIndex;
     _pendingLinkIndexFrom = InvalidNodeIndex;
 }