/// <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; } } }
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(); }
/// <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); }
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); }
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 ? '*' : '&'); } }
/// <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); }
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(']'); }
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()); }
/// <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; } } }
/// <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; } }
/// <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; }