void Undo(CharSpan charSpan)
 {
     Debug.Assert(nextCharSpan == null);
     if (nextCharSpan != null)
     {
         throw new InvalidOperationException();
     }
     nextCharSpan = charSpan;
 }
Example #2
0
        public bool TryGetBaseMaterialId(CharSpan idSpan, out MaterialId materialId)
        {
            for (int i = 0; i < baseMaterialInfos.Length; i++)
            {
                if (baseMaterialInfos[i].materialName == idSpan)
                {
                    materialId = new MaterialId(i + 1, 0);
                    return(true);
                }
            }

            materialId = default;
            return(false);
        }
Example #3
0
 /// <summary>
 /// Get or add this value to the StringTable.
 /// </summary>
 /// <remarks>
 /// The CharSpan type lets us refer to a slice of an underlying string (to allow splitting strings without allocating).
 /// </remarks>
 public virtual StringId GetOrAdd(CharSpan value)
 {
     if (m_entries.TryGetValue(value, out StringId id))
     {
         return(id);
     }
     else
     {
         id = m_stringTable.Add(value.AsSpan(m_stringTable));
         // and add the entry as a reference to our own backing store, not the one passed in
         // (since the value passed in is probably holding onto part of an actual string)
         m_entries.Add(new CharSpan(id), id);
         return(id);
     }
 }
Example #4
0
        public bool TryGetMaterialProperty(MaterialId materialId, CharSpan propertySpan, out MaterialPropertyInfo materialPropertyInfo)
        {
            MaterialInfo materialInfo = baseMaterialInfos[materialId.baseId - 1];

            for (int i = materialInfo.propertyRange.start; i < materialInfo.propertyRange.end; i++)
            {
                if (materialProperties[i].propertyName == propertySpan)
                {
                    materialPropertyInfo = materialProperties[i];
                    return(true);
                }
            }

            materialPropertyInfo = default;
            return(false);
        }
Example #5
0
 /// <summary>
 /// Splits the original span with the given splitter
 /// </summary>
 /// <param name="original">The span to be split</param>
 /// <param name="splitter">The splitter</param>
 /// <param name="rest">The second part of the resulting split</param>
 /// <returns>The first part of the resulting split</returns>
 public static CharSpan Split(CharSpan original, CharSpan splitter, out CharSpan rest)
 {
     if (original.spanBegin == splitter.spanBegin)
     {
         rest = NULL;
         if (original.spanEnd == splitter.spanEnd)
         {
             return(NULL);
         }
         return(new CharSpan(System.Convert.ToChar(splitter.spanEnd + 1), original.spanEnd));
     }
     if (original.spanEnd == splitter.spanEnd)
     {
         rest = NULL;
         return(new CharSpan(original.spanBegin, System.Convert.ToChar(splitter.spanBegin - 1)));
     }
     rest = new CharSpan(System.Convert.ToChar(splitter.spanEnd + 1), original.spanEnd);
     return(new CharSpan(original.spanBegin, System.Convert.ToChar(splitter.spanBegin - 1)));
 }
Example #6
0
        /// <summary>
        /// Repacks all the transitions from this state to remove overlaps between the transitions' values
        /// </summary>
        public void RepackTransitions()
        {
            Dictionary <DFAState, List <CharSpan> > inverse = new Dictionary <DFAState, List <CharSpan> >();

            foreach (KeyValuePair <CharSpan, DFAState> transition in transitions)
            {
                if (!inverse.ContainsKey(transition.Value))
                {
                    inverse.Add(transition.Value, new List <CharSpan>());
                }
                inverse[transition.Value].Add(transition.Key);
            }
            transitions.Clear();
            foreach (DFAState child in inverse.Keys)
            {
                List <CharSpan> keys = inverse[child];
                keys.Sort(new System.Comparison <CharSpan>(CharSpan.Compare));
                for (int i = 0; i != keys.Count; i++)
                {
                    CharSpan k1 = keys[i];
                    for (int j = i + 1; j != keys.Count; j++)
                    {
                        CharSpan k2 = keys[j];
                        if (k2.Begin == k1.End + 1)
                        {
                            k1      = new CharSpan(k1.Begin, k2.End);
                            keys[i] = k1;
                            keys.RemoveAt(j);
                            j--;
                        }
                    }
                }
                foreach (CharSpan key in keys)
                {
                    transitions.Add(key, child);
                }
            }
        }
Example #7
0
 /// <summary>
 /// Removes a transition from this state
 /// </summary>
 /// <param name="value">The value on the transition</param>
 public void RemoveTransition(CharSpan value)
 {
     transitions.Remove(value);
 }
Example #8
0
 /// <summary>
 /// Initializes this transition
 /// </summary>
 /// <param name="span">The transition's value</param>
 /// <param name="next">The next state by this transition</param>
 public NFATransition(CharSpan span, NFAState next)
 {
     this.span = span;
     this.next = next;
 }
			public CharSpan3(CharSpan item1, CharSpan? item2 = null, CharSpan? item3 = null) {
				Item1 = item1;
				Item2 = item2;
				Item3 = item3;
			}
		void Undo(CharSpan charSpan) {
			Debug.Assert(nextCharSpan == null);
			if (nextCharSpan != null)
				throw new InvalidOperationException();
			nextCharSpan = charSpan;
		}
Example #11
0
		// Copy the values of this character span to the given span.
		public void CopyTo(CharSpan span)
				{
					span.start = start;
					span.length = length;
					span.pixelWidth = pixelWidth;
					span.newline = newline;
				}
Example #12
0
		// Calculate text metrics information.
		//
		// Note that this is currently broken. Turn this on at your own risk.
		public Size GetBounds
					(Graphics graphics, String text, Font font,
					 SizeF layoutSize, StringFormat format,
					 out int charactersFitted, out int linesFilled)
				{
					// set the current graphics
					this.graphics = graphics;

					// set the current toolkit graphics
					this.toolkitGraphics = graphics.ToolkitGraphics;

					// set the current text
					this.text = text;

					// set the current font
					this.font = font;

					// ensure we have a string format
					if(format == null) { format = SF_DEFAULT; }

					// set the current string format
					this.format = format;

					// set the current layout rectangle
					this.layout = new Rectangle
						(0, 0, (int)layoutSize.Width, (int)layoutSize.Height);

					// set the current line height
					lineHeight = font.Height;

					// set the only whole lines flag
					onlyWholeLines = (((format.FormatFlags &
					                    StringFormatFlags.LineLimit) != 0) ||
					                  ((format.Trimming &
					                    StringTrimming.None) != 0));

					// set the index of the next character
					nextIndex = 0;

					// set the current line space usage
					lineSpaceUsedUp = 0;

					// set the previous span ended in new line flag
					prevIsNewLine = false;

					// select the current font into the graphics context
					graphics.SelectFont(font);

					// set the text width
					int textWidth = 0;

					// set the maximum width
					int maxWidth = 0;

					// set the default characters fitted
					charactersFitted = 0;

					// set the default lines filled
					linesFilled = 0;

					// remove the hotkey prefix, if needed
					if(format.HotkeyPrefix != HotkeyPrefix.None)
					{
						// get the hotkey index
						hotkeyIndex = text.IndexOf('&');

						// handle the hotkey as needed
						if(hotkeyIndex != -1)
						{
							if(hotkeyIndex < (text.Length - 1) &&
							   !Char.IsControl(text[hotkeyIndex + 1]))
							{
								// remove the hotkey character
								text = text.Substring(0, hotkeyIndex) +
								       text.Substring(hotkeyIndex + 1);

								// set the current text
								this.text = text;

								// update characters fitted
								++charactersFitted;
							}

							// no need for this anymore
							hotkeyIndex = -1;
						}
					}

					// create character spans
					CharSpan span = new CharSpan();
					CharSpan prev = new CharSpan();

					// set the first span flag
					bool firstSpan = true;

					// set the measure trailing spaces flag
					bool mts = ((format.FormatFlags &
					             StringFormatFlags.MeasureTrailingSpaces) != 0);

					// process the text
					while(nextIndex < text.Length)
					{
						// get the next span of characters
						GetNextSpan(span);

						// handle span on new line
						if(span.newline)
						{
							// remove trailing spaces, if needed
							if(!firstSpan && !mts && text[prev.start] == ' ')
							{
								// update the text width
								textWidth -= GetSpanWidth(prev);
							}

							// update the maximum width, if needed
							if(textWidth > maxWidth) { maxWidth = textWidth; }

							// update the text width
							textWidth = 0;

							// update the lines filled
							++linesFilled;
						}

						// update the text width
						textWidth += GetSpanWidth(span);

						// update the characters fitted
						charactersFitted += span.length;

						// copy span values to previous span
						span.CopyTo(prev);
					}

					// update the maximum width, if needed
					if(textWidth > maxWidth) { maxWidth = textWidth; }

					// update the lines filled to account for the first line
					++linesFilled;

					// update the maximum width, if needed
					if(maxWidth > layout.Width) { maxWidth = layout.Width; }

					// calculate the height
					int height = (lineHeight * linesFilled);

					// update the height, if needed
					if(height > layout.Height) { height = layout.Height; }

					// return the size of the text
					return new Size(maxWidth, height);
				}
Example #13
0
 public CharSpan3(CharSpan item1, CharSpan?item2 = null, CharSpan?item3 = null)
 {
     Item1 = item1;
     Item2 = item2;
     Item3 = item3;
 }
Example #14
0
 /// <summary>
 /// Adds a transition from this state
 /// </summary>
 /// <param name="value">The value on the transition</param>
 /// <param name="next">The next state by the transition</param>
 public void AddTransition(CharSpan value, DFAState next)
 {
     transitions.Add(value, next);
 }
Example #15
0
		// Calculate whether a word wraps to a new line.
		private void CheckForWrap(CharSpan span)
				{
					// bail out now if there's nothing to do
					if(span.length == 0) { return; }

					// reset the line space usage, if needed
					if(span.newline) { lineSpaceUsedUp = 0; }

					// get the first character of the span
					char c = text[span.start];

					// handle unwrappable span, if needed
					if(c != ' ' &&
					   ((format.FormatFlags & StringFormatFlags.NoWrap) == 0))
					{
						// get the width of the span
						int width = GetSpanWidth(span);

						// handle wrapping of span, as needed
						if((lineSpaceUsedUp + width) > layout.Width)
						{
							// handle unwrappable span trimming, if needed
							if(width > layout.Width)
							{
								// trim the span
								span.length = TrimTextToChar
									(span.start, span.length, layout.Width,
									 out span.pixelWidth);

								// update the text position
								nextIndex = span.start + span.length;

								// set the new line flag, if needed
								if(lineNumber > 0) { span.newline = true; }

								// set the previous span ended in new line flag
								prevIsNewLine = true;
							}

							// reset line space usage
							lineSpaceUsedUp = 0;

							// set the new line flag
							span.newline = true;
						}
					}

					// update line space usage
					lineSpaceUsedUp += GetSpanWidth(span);
				}
Example #16
0
 bool VerifyEndLabel(CharSpan chars)
 {
     return(chars
            .LastWord()
            .StartsWith(_hereDocLabel));
 }
Example #17
0
		// Get the width of the span in pixels.
		private int GetSpanWidth(CharSpan span)
				{
					// set the width of the span, if needed
					if(span.pixelWidth == -1)
					{
						// get the text of the span
						String s = text.Substring(span.start, span.length);

						// declare out variables
						int cf, lf;

						// set the width of the span
						span.pixelWidth = toolkitGraphics.MeasureString
							(s, MEASURE_LAYOUT_RECT, format, out cf, out lf,
							 false).Width;
					}

					// return the width of the span
					return span.pixelWidth;
				}
Example #18
0
		// Get the next span of characters.
		private void GetNextSpan(CharSpan span)
				{
					// set new line flag
					bool newline = false;

					// get the start index
					int start = nextIndex;

					// handle whitespace span
					while(nextIndex < text.Length && text[nextIndex] == ' ')
					{
						++nextIndex;
					}

					// handle word span
					if(nextIndex == start)
					{
						// find the end of the word
						while(nextIndex < text.Length)
						{
							// get the current character
							char c = text[nextIndex];

							// find the end of the word
							if(c == ' ' || c == '\n' || c == '\r') { break; }

							// we also split on minus to mimic MS behavior
							if(c == '-')
							{
								nextIndex++;
								break;
							}

							// move to the next character
							++nextIndex;
						}
					}

					// get the length of the span
					int length = nextIndex - start;

					// handle new line characters
					if(nextIndex < text.Length)
					{
						// get the current character
						char c = text[nextIndex];

						// check for new line characters
						if(c == '\r')
						{
							// move past the carriage return
							++nextIndex;

							// move past the line feed, if needed
							if(nextIndex < text.Length &&
							   text[nextIndex] == '\n')
							{
								++nextIndex;
							}

							// set the new line flag
							newline = true;
						}
						else if(c == '\n')
						{
							// move past the line feed
							++nextIndex;

							// set the new line flag
							newline = true;
						}
					}

					// set the span values
					span.Set(start, length, prevIsNewLine);

					// update the previous span ended in new line flag
					prevIsNewLine = newline;

					// handle wrapping
					CheckForWrap(span);
				}
Example #19
0
 /// <summary>
 /// Gets the child state by the specified transition
 /// </summary>
 /// <param name="value">The value on the transition</param>
 /// <returns>The child state</returns>
 public DFAState GetChildBy(CharSpan value)
 {
     return(transitions[value]);
 }
Example #20
0
 /// <summary>
 /// Determines whether this state has the specified transition
 /// </summary>
 /// <param name="value">The value on the transition</param>
 /// <returns><c>true</c> if this state has the specified transition; otherwise, <c>false</c></returns>
 public bool HasTransition(CharSpan value)
 {
     return(transitions.ContainsKey(value));
 }
Example #21
0
		// Calculate and draw the string by drawing each line.
		public void Draw
					(Graphics graphics, String text, Font font,
					 Rectangle drawLayout, StringFormat format, Brush brush)
				{
					// set the current graphics
					this.graphics = graphics;

					// set the current toolkit graphics
					this.toolkitGraphics = graphics.ToolkitGraphics;

					// set the current text
					this.text = text;

					// set the current font
					this.font = font;

					// set the current layout rectangle
					this.layout = drawLayout;

					// set the current brush
					this.brush = brush;

					// ensure we have a string format
					if(format == null) { format = SF_DEFAULT; }

					// set the current string format
					this.format = format;

					// set the default hotkey index
					this.hotkeyIndex = -1;

					// set the current line height
					lineHeight = font.Height;

					// set the only whole lines flag
					onlyWholeLines = (((format.FormatFlags &
					                    StringFormatFlags.LineLimit) != 0) ||
					                  ((format.Trimming &
					                    StringTrimming.None) != 0));

					// set the index of the next character
					nextIndex = 0;

					// set the current line space usage
					lineSpaceUsedUp = 0;

					// set the current line number
					lineNumber = 0;

					// set the previous span ended in new line flag
					prevIsNewLine = false;

					// select the current font into the graphics context
					graphics.SelectFont(font);

					// select the current brush into the graphics context
					graphics.SelectBrush(brush);

					// set the current text start
					int textStart = 0;

					// set the current text length
					int textLength = 0;

					// set the current text width
					int textWidth = 0;

					// get the actual hotkey index, if needed
					if(format.HotkeyPrefix != HotkeyPrefix.None)
					{
						// get the hotkey index
						hotkeyIndex = text.IndexOf('&');

						// handle the hotkey as needed
						if(hotkeyIndex != -1)
						{
							if(hotkeyIndex >= (text.Length - 1) ||
							   Char.IsControl(text[hotkeyIndex + 1]))
							{
								// no need for this anymore
								hotkeyIndex = -1;
							}
							else
							{
								// remove the hotkey character
								text = text.Substring(0, hotkeyIndex) +
								       text.Substring(hotkeyIndex + 1);

								// set the current text
								this.text = text;

								// prepare to show or hide the underline
								if(format.HotkeyPrefix == HotkeyPrefix.Show)
								{
									// get the underline font
									underlineFont = new Font
										(font, font.Style | FontStyle.Underline);
								}
								else
								{
									// no need for this anymore
									hotkeyIndex = -1;
								}
							}
						}
					}

					// draw the text
					try
					{
						// handle drawing based on line alignment
						if(format.LineAlignment == StringAlignment.Near)
						{
							// set the current y position
							int y = layout.Top;

							// get the maximum y position
							int maxY = layout.Bottom;

							// adjust for whole lines, if needed
							if(onlyWholeLines)
							{
								maxY -= ((maxY - y) % lineHeight);
							}

							// get the last line y position
							int lastLineY = maxY - lineHeight;

							// create character spans
							CharSpan span = new CharSpan();
							CharSpan prev = new CharSpan();

							// set the first span flag
							bool firstSpan = true;

							// process the text
							while(nextIndex < text.Length)
							{
								// get the next span of characters
								GetNextSpan(span);

								// draw the pending line, as needed
								if(span.newline && !firstSpan)
								{
									// draw the line, if needed
									if(textWidth > 0)
									{
										// remove trailing spaces, if needed
										if(!firstSpan && text[prev.start] == ' ')
										{
											// update text width
											textWidth -= GetSpanWidth(prev);

											// update text length
											textLength -= prev.length;
										}

										// draw the line
										DrawLine
											(textStart, textLength, textWidth,
											 y, (y > lastLineY));
									}

									// update the y position
									y += lineHeight;

									// update the line number
									++lineNumber;

									// update the text start
									textStart = span.start;

									// reset the text length
									textLength = 0;

									// reset the text width
									textWidth = 0;
								}

								// update the text length
								textLength += span.length;

								// update the text width
								textWidth += GetSpanWidth(span);

								// copy span values to previous span
								span.CopyTo(prev);

								// set the first span flag
								firstSpan = false;

								// break if the y position is out of bounds
								if(y > maxY) { break; }
							}

							// draw the last line, if needed
							if(textWidth > 0 && y <= maxY)
							{
								// draw the last line
								DrawLine
									(textStart, textLength, textWidth, y,
									 (y > lastLineY));
							}
						}
						else
						{
							// set default lines to draw
							int linesToDraw = 0;

							// calculate lines to draw
							if(onlyWholeLines)
							{
								linesToDraw = layout.Height / lineHeight;
							} 
							else
							{
								linesToDraw = (int)Math.Ceiling((double)layout.Height / lineHeight);
							}

							// create line span list
							LineSpan[] lines = new LineSpan[linesToDraw];

							// create character spans
							CharSpan span = new CharSpan();
							CharSpan prev = new CharSpan();

							// set the first span flag
							bool firstSpan = true;

							// set the current line position
							int linePos = 0;

							// populate line span list
							while(linePos < lines.Length &&
							      nextIndex < text.Length)
							{
								// get the next span of characters
								GetNextSpan(span);

								// handle span on new line
								if(span.newline && !firstSpan)
								{
									// remove trailing spaces, if needed
									if(!firstSpan && text[prev.start] == ' ')
									{
										// update text width
										textWidth -= GetSpanWidth(prev);

										// update text length
										textLength -= prev.length;
									}

									// create line span for current line
									LineSpan lineSpan = new LineSpan
										(textStart, textLength, textWidth);

									// add current line span to line span list
									lines[linePos++] = lineSpan;

									// update text start
									textStart = span.start;

									// update text length
									textLength = 0;

									// update text width
									textWidth = 0;
								}

								// update text length
								textLength += span.length;

								// update text width
								textWidth += GetSpanWidth(span);

								// copy span values to previous span
								span.CopyTo(prev);

								// set the first span flag
								firstSpan = false;
							}

							// add the last line to the line span list
							if(linePos < lines.Length)
							{
								// create line span for last line
								LineSpan lineSpan = new LineSpan
									(textStart, textLength, textWidth);

								// add last line span to the line span list
								lines[linePos++] = lineSpan;
							}

							// calculate the top line y
							int y = (layout.Height - (linePos * lineHeight));

							// adjust y for center alignment, if needed
							if(format.LineAlignment == StringAlignment.Center)
							{
								y /= 2;
							}

							// translate y to layout rectangle
							y += layout.Top;

							// adjust line position to last line
							--linePos;

							// draw the lines
							for(int i = 0; i < linePos; ++i)
							{
								// get the current line
								LineSpan line = lines[i];

								// draw the current line
								DrawLine
									(line.start, line.length, line.pixelWidth,
									 y, false);

								// update the y position
								y += lineHeight;
							}

							// draw the last line
							DrawLine
								(lines[linePos].start, lines[linePos].length,
								 lines[linePos].pixelWidth, y, true);
						}
					}
					finally
					{
						// dispose the underline font, if we have one
						if(underlineFont != null)
						{
							// dispose the underline font
							underlineFont.Dispose();

							// reset the underline font
							underlineFont = null;
						}
					}
				}
Example #22
0
        // public static string ListToString(IList<string> list, string separator = ", ") {
        //     if (list == null || list.Count == 0) {
        //         return string.Empty;
        //     }
        //
        //     string retn = null;
        //     TextUtil.StringBuilder.Clear();
        //
        //     for (int i = 0; i < list.Count; i++) {
        //         TextUtil.StringBuilder.Append(list[i]);
        //         if (i != list.Count - 1 && separator != null) {
        //             TextUtil.StringBuilder.Append(separator);
        //         }
        //     }
        //
        //     retn = TextUtil.StringBuilder.ToString();
        //     TextUtil.StringBuilder.Clear();
        //     return retn;
        // }

        public static unsafe bool EqualsRangeUnsafe(string str, CharSpan span)
        {
            return(EqualsRangeUnsafe(str, span.data, span.rangeStart, span.rangeEnd - span.rangeStart));
        }
Example #23
0
 /// <summary>
 /// Adds a transition from this state to the given state on the given value
 /// </summary>
 /// <param name="value">The new transition's value</param>
 /// <param name="next">The next state by the new transition</param>
 public void AddTransition(CharSpan value, NFAState next)
 {
     transitions.Add(new NFATransition(value, next));
 }
Example #24
0
        /// <summary>
        /// Normalizes this set
        /// </summary>
        public void Normalize()
        {
            // Trace if modification has occured
            bool modification = true;

            // Repeat while modifications occured
            while (modification)
            {
                modification = false;
                // For each NFA state in the set
                for (int s1 = 0; s1 != backend.Count; s1++)
                {
                    // For each transition in this NFA state Set[s1]
                    for (int t1 = 0; t1 != backend[s1].Transitions.Count; t1++)
                    {
                        // If this is an ε transition, go to next transition
                        if (backend[s1].Transitions[t1].Span.Equals(NFA.EPSILON))
                        {
                            continue;
                        }
                        //Confront to each transition in each NFA state of the set
                        for (int s2 = 0; s2 != backend.Count; s2++)
                        {
                            for (int t2 = 0; t2 != backend[s2].Transitions.Count; t2++)
                            {
                                if (backend[s2].Transitions[t2].Span.Equals(NFA.EPSILON))
                                {
                                    continue;
                                }
                                // If these are not the same transitions of the same state
                                if ((s1 != s2) || (t1 != t2))
                                {
                                    // If the two transition are equal : do nothing
                                    if (backend[s1].Transitions[t1].Span.Equals(backend[s2].Transitions[t2].Span))
                                    {
                                        continue;
                                    }
                                    // Get the intersection of the two spans
                                    CharSpan Inter = CharSpan.Intersect(backend[s1].Transitions[t1].Span, backend[s2].Transitions[t2].Span);
                                    // If no intersection : do nothing
                                    if (Inter.Length == 0)
                                    {
                                        continue;
                                    }

                                    // Split transition1 in 1, 2 or 3 transitions and modifiy the states accordingly
                                    CharSpan Part1;
                                    CharSpan Part2;
                                    Part1 = CharSpan.Split(backend[s1].Transitions[t1].Span, Inter, out Part2);
                                    backend[s1].ReplaceTransition(t1, new NFATransition(Inter, backend[s1].Transitions[t1].Next));
                                    if (Part1.Length != 0)
                                    {
                                        backend[s1].AddTransition(Part1, backend[s1].Transitions[t1].Next);
                                    }
                                    if (Part2.Length != 0)
                                    {
                                        backend[s1].AddTransition(Part2, backend[s1].Transitions[t1].Next);
                                    }

                                    // Split transition2 in 1, 2 or 3 transitions and modifiy the states accordingly
                                    Part1 = CharSpan.Split(backend[s2].Transitions[t2].Span, Inter, out Part2);
                                    backend[s2].ReplaceTransition(t2, new NFATransition(Inter, backend[s2].Transitions[t2].Next));
                                    if (Part1.Length != 0)
                                    {
                                        backend[s2].AddTransition(Part1, backend[s2].Transitions[t2].Next);
                                    }
                                    if (Part2.Length != 0)
                                    {
                                        backend[s2].AddTransition(Part2, backend[s2].Transitions[t2].Next);
                                    }
                                    modification = true;
                                }
                            }
                        }
                    }
                }
            }
        }
		CharSpan3 GetNextName(CharSpan item1) {
			Debug.Assert(item1.Kind == TokenKind.Name);
			var item2 = GetNextSpan();
			if (item2 == null || item2.Value.Span.Length != 1 || item2.Value.Kind != TokenKind.Colon) {
				if (item2 != null)
					Undo(item2.Value);
				return new CharSpan3(item1);
			}
			var item3 = GetNextSpan();
			if (item3 == null || item3.Value.Kind != TokenKind.Name) {
				if (item3 != null)
					Undo(item3.Value);
				return new CharSpan3(item1, item2);
			}
			return new CharSpan3(item1, item2, item3);
		}
Example #26
0
 /// <summary>
 /// Compares the left and right spans for a decreasing order sort
 /// </summary>
 /// <param name="left">The left span</param>
 /// <param name="right">The right span</param>
 /// <returns>The order between left and right</returns>
 public static int CompareReverse(CharSpan left, CharSpan right)
 {
     return(right.spanBegin.CompareTo(left.spanBegin));
 }
Example #27
0
        /// <summary>
        /// Tries to convert a reparse point target path to its absolute path representation. If a supplied
        /// <paramref name="reparsePointTargetPath"/> is not a relative path, it's returned unchanged.
        /// </summary>
        public static string ConvertReparsePointTargetPathToAbsolutePath(string reparsePointPath, string reparsePointTargetPath)
        {
            // NOTE: Don't use anything from .NET Path that causes failure in handling long path.

            bool startWithDotSlash = reparsePointTargetPath.Length >= 2 &&
                                     reparsePointTargetPath[0] == '.' &&
                                     (reparsePointTargetPath[1] == Path.DirectorySeparatorChar ||
                                      reparsePointTargetPath[1] == Path.AltDirectorySeparatorChar);
            bool startWithDotDotSlash = reparsePointTargetPath.Length >= 3 &&
                                        reparsePointTargetPath[0] == '.' &&
                                        reparsePointTargetPath[1] == '.' &&
                                        (reparsePointTargetPath[2] == Path.DirectorySeparatorChar ||
                                         reparsePointTargetPath[2] == Path.AltDirectorySeparatorChar);

            if (!startWithDotSlash && !startWithDotDotSlash)
            {
                // reparsePointTargetPath is already an absolute path
                return(reparsePointTargetPath);
            }

            var possibleVolumeBoundary = VerifyReparsePointPathAndIdentifyVolumeBoundary(reparsePointPath);

            if (!possibleVolumeBoundary.Succeeded)
            {
                throw new BuildXLException(CreateErrorMessage(possibleVolumeBoundary.Failure.Describe()));
            }

            int volumeBoundary = possibleVolumeBoundary.Result;

            StringSegment reparsePoint       = reparsePointPath;
            StringSegment reparsePointTarget = reparsePointTargetPath;

            using (var wrapper = StringSegmentListPool.GetInstance())
            {
                List <StringSegment> components = wrapper.Instance;

                var possibleResult = ParseAndAddPathComponents(components, CharSpan.Skip(reparsePoint, volumeBoundary));
                if (!possibleResult.Succeeded)
                {
                    throw new BuildXLException(CreateErrorMessage(possibleResult.Failure.Describe()));
                }

                // there must be at least one path component
                Contract.Assert(components.Count > 0);

                // we need to remove the last path component (we are 'replacing' it with target path components)
                components.RemoveAt(components.Count - 1);

                possibleResult = ParseAndAddPathComponents(components, reparsePointTarget);
                if (!possibleResult.Succeeded)
                {
                    throw new BuildXLException(CreateErrorMessage(possibleResult.Failure.Describe()));
                }

                using (var sbWrapper = Pools.GetStringBuilder())
                {
                    StringBuilder builder = sbWrapper.Instance;

                    reparsePoint.Subsegment(0, volumeBoundary).CopyTo(builder);

                    foreach (var pathSegment in components)
                    {
                        builder.Append(Path.DirectorySeparatorChar);
                        pathSegment.CopyTo(builder);
                    }

                    return(builder.ToString());
                }
            }

            string CreateErrorMessage(string detailedMessage)
            {
                return(I($"Failed to convert reparse point target path to absolute path ('{reparsePointPath}' -> '{reparsePointTargetPath}'). {detailedMessage}"));
            }
        }