public CssUnitHandlers RequireSet(char character) { if (Handlers == null) { // Create the map: Handlers = new List <CssUnitHandlers>(1); } // Already got a set for this character? Linear scan is faster than a hashtable here. int count = Handlers.Count; for (int i = 0; i < count; i++) { if (Handlers[i].Character == character) { return(Handlers[i]); } } // Create the set: CssUnitHandlers set = new CssUnitHandlers(); set.Character = character; Handlers.Add(set); return(set); }
public void Add(string text, Css.Value value) { // Get the letters of the text, e.g. px: char[] pieces = text.ToCharArray(); // Run through the "tree" of handlers, creating them. This is to maximise parse speed. CssUnitHandlers handlerSet = this; for (int i = 1; i < pieces.Length; i++) { char current = pieces[i]; handlerSet = handlerSet.RequireSet(current); } // Apply the value: handlerSet.Value = value; }
/// <summary>Adds a CSS at rule to the global set.</summary> /// <param name="cssUnit">The at rule to add.</param> /// <returns>True if adding it was successful.</returns> private static void AddToSet(string[] names, Dictionary <char, CssUnitHandlers> set, CssUnit cssUnit) { for (int i = 0; i < names.Length; i++) { string text = names[i]; char first = text[0]; CssUnitHandlers handlers; if (!set.TryGetValue(first, out handlers)) { // Create it: handlers = new CssUnitHandlers(); handlers.Character = first; set[first] = handlers; } handlers.Add(text, cssUnit); } }
/// <summary>Attempts to handle the given lexer with this units set.</summary> public Css.Value Handle(CssLexer lexer, bool removeAll) { // By peeking, get as far as we can until a delim of any kind is reached, or we can't go any further. // e.g. 41px*50% - the first will terminate successfully at the x. // Note that we know the current peek matches character. CssUnitHandlers handler = this; int currentIndex = 1; while (true) { // Get the char: char letter = lexer.Peek(currentIndex); currentIndex++; // Got a handler for it? if (handler.Handlers == null) { // Nope! handler.Value, if there is one, is the furthest we can go. break; } int handlerSetCount = handler.Handlers.Count; // Linear scan is faster than a hashtable here. for (int i = 0; i < handlerSetCount; i++) { if (handler.Handlers[i].Character == letter) { // Got it! Keep going. handler = handler.Handlers[i]; goto NextLetter; } } // No letter matches. Stop there. break; NextLetter: continue; } if (handler.Value != null) { // Read off the amount we read now. int start = 2; if (removeAll) { start = 1; } for (int i = start; i < currentIndex; i++) { lexer.Read(); } } return(handler.Value); }