/Source/AniseLib/Core/AniseScript.cs
http://anise.codeplex.com · C# · 301 lines · 253 code · 40 blank · 8 comment · 53 complexity · 7b99034d63279ee45c5b626d216193f0 MD5 · raw file
- //
- // Anise - A user-friendly dependency injection engine
- // Released by Microsoft Live Labs
- //
- // This source code is released under the Microsoft Code Sharing License.
- // For full details, see: http://anise.codeplex.com/license
- //
-
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
-
- using Microsoft.LiveLabs.Anise.API;
-
- namespace Microsoft.LiveLabs.Anise.Core
- {
- internal class AniseScript
- {
- public override String ToString()
- {
- StringBuilder builder = new StringBuilder();
- bool needsNewLine = false;
- foreach (AniseScriptLine line in m_lines)
- {
- if (needsNewLine) builder.Append('\n');
- builder.Append(line.Text);
- needsNewLine = true;
- }
- return builder.ToString();
- }
-
- internal AniseScript() : this("")
- {
- // Do nothing.
- }
-
- internal AniseScript(String text)
- {
- m_lines = new List<AniseScriptLine>();
- m_consumeBuilder = new StringBuilder();
- this.LoadText(text);
- }
-
- internal List<AniseScriptLine> Lines
- {
- get { return m_lines; }
- }
-
- internal char CurrentChar
- {
- get
- {
- AniseScriptLine line = this.CurrentLine;
- if (line == null) return AniseConstants.EndOfData;
- if (this.CurrentLine.Text.Length == m_positionIndex)
- {
- return (m_lineIndex + 1 == m_lines.Count) ? AniseConstants.EndOfData : '\n';
- }
- return this.CurrentLine.Text[m_positionIndex];
- }
- }
-
- internal AniseScriptLine CurrentLine
- {
- get
- {
- if (m_lines.Count == 0) return null;
- if (m_lineIndex >= m_lines.Count) return null;
- return m_lines[m_lineIndex];
- }
- }
-
- internal AniseScriptPosition CurrentPosition
- {
- get
- {
- AniseScriptLine line = this.CurrentLine;
- if ((line == null) || (line.Position == null))
- {
- return new AniseScriptPosition(AniseConstants.DefaultFile, 1, 1);
- }
- else
- {
- return new AniseScriptPosition(this.CurrentLine.Position.SourceFile,
- this.CurrentLine.Position.LineNumber, m_positionIndex + 1);
- }
- }
- }
-
- internal List<AniseScriptLine> LoadText(String text)
- {
- if (text == null) throw new ArgumentNullException("Text cannot be null");
- if (text == "") return new List<AniseScriptLine>();
-
- List<AniseScriptLine> newLines = this.ConvertToLines(text, AniseConstants.DefaultFile + m_inlineChunks);
- m_lines.AddRange(newLines);
- m_inlineChunks++;
-
- return newLines;
- }
-
- internal List<AniseScriptLine> LoadFile(String fileName, AniseScriptLine replacingLine)
- {
- List<AniseScriptLine> newLines = this.ConvertToLines(File.ReadAllText(fileName), fileName);
- int index = m_lines.IndexOf(replacingLine);
- if (index != -1)
- {
- m_lines.InsertRange(index + 1, newLines);
- }
- else
- {
- m_lines.AddRange(newLines);
- }
-
- return newLines;
- }
-
- internal void RemoveLines(List<AniseScriptLine> lines)
- {
- foreach (AniseScriptLine line in lines)
- {
- m_lines.Remove(line);
- }
- }
-
- internal char Advance()
- {
- if (this.IsFinished) return AniseConstants.EndOfData;
-
- String lineText = this.CurrentLine.Text;
- if (m_positionIndex + 1 > lineText.Length)
- {
- m_lineIndex++;
- m_positionIndex = 0;
- }
- else
- {
- m_positionIndex++;
- }
- return this.CurrentChar;
- }
-
- internal void AdvancePastWhitespace()
- {
- while (Char.IsWhiteSpace(this.CurrentChar))
- {
- this.Advance();
- }
- }
-
- internal String ConsumeTo(String stopChars)
- {
- m_consumeBuilder.Length = 0;
- bool quoted = false;
- bool escaped = false;
- bool insertWhitespace = false;
- while (true)
- {
- char c = this.CurrentChar;
- if (escaped)
- {
- if (quoted && (c != AniseConstants.DoubleQuote) && (c != AniseConstants.Backslash))
- {
- m_consumeBuilder.Append(AniseConstants.Backslash);
- }
-
- m_consumeBuilder.Append(c);
- escaped = false;
- }
- else if (c == AniseConstants.Backslash)
- {
- escaped = true;
- }
- else if (c == AniseConstants.DoubleQuote)
- {
- quoted = !quoted;
- }
- else if (quoted && (c != AniseConstants.EndOfData))
- {
- if (insertWhitespace)
- {
- m_consumeBuilder.Append(' ');
- insertWhitespace = false;
- }
- m_consumeBuilder.Append(c);
- }
- else if (Char.IsWhiteSpace(c))
- {
- insertWhitespace = true;
- }
- else
- {
- if (stopChars.Contains(c)) break;
- if (c == AniseConstants.EndOfData) throw new AniseException(
- "Expected '" + stopChars.ToString() + "'", this.CurrentPosition);
-
- if (insertWhitespace)
- {
- m_consumeBuilder.Append(' ');
- insertWhitespace = false;
- }
- m_consumeBuilder.Append(c);
- }
- this.Advance();
- }
-
- String result = m_consumeBuilder.ToString();
- return result;
- }
-
- internal bool IsFinished
- {
- get
- {
- return (m_lineIndex >= m_lines.Count);
- }
- }
-
- private List<AniseScriptLine> ConvertToLines(String rawText, String fileName)
- {
- List<AniseScriptLine> lines = new List<AniseScriptLine>();
- int lineNumber = 1;
- using (StringReader reader = new StringReader(rawText))
- {
- while (true)
- {
- String line = reader.ReadLine();
- if (line == null) break;
- lines.Add(new AniseScriptLine(new AniseScriptPosition(fileName, lineNumber, 1), null, line));
- lineNumber++;
- }
- }
- return lines;
- }
-
- private List<AniseScriptLine> m_lines;
-
- private StringBuilder m_consumeBuilder;
-
- private int m_inlineChunks;
-
- private int m_lineIndex;
-
- private int m_positionIndex;
- }
-
- internal class AniseScriptLine
- {
- public override string ToString()
- {
- return Path.GetFileName(this.Position.SourceFile) + "@" + this.Position.LineNumber + ": " + this.Text;
- }
-
- internal AniseScriptLine(AniseScriptPosition position, String namespaceText, String text)
- {
- this.Position = position;
- this.Namespace = namespaceText;
- this.Text = text;
- }
-
- internal AniseScriptPosition Position
- {
- get { return m_position; }
-
- set
- {
- if (value == null) throw new ArgumentNullException("Position cannot be null");
- m_position = value;
- }
- }
-
- internal String Namespace
- {
- get { return m_namespace; }
-
- set
- {
- m_namespace = value;
- }
- }
-
- internal String Text
- {
- get { return m_text; }
-
- set
- {
- if (value == null) throw new ArgumentNullException("Text cannot be null");
- m_text = value;
- }
- }
-
- private AniseScriptPosition m_position;
-
- private String m_namespace;
-
- private String m_text;
- }
- }