/// <summary> /// Process all the <code>@include</code> directives in the file. /// </summary> /// <param name="lines">Source file lines</param> /// <returns>An enumerable object containing the lines of the source code after the inclusions</returns> private async Task <IEnumerable <string> > ProcessIncludes(string[] lines) { LinkedList <string> result = new LinkedList <string>(); foreach (string line in lines) { if (line.StartsWith("@include")) { string includeSrc = await ProcessSingleInclude(line); includeSrc = SiiTextParser.SanitizeSource(includeSrc); foreach (string includeLine in SiiTextParser.SplitSourceToLines(includeSrc)) { result.AddLast(includeLine); } } else { result.AddLast(line); } } return(result); }
/// <summary> /// Parse a Sii unit object. /// </summary> /// <param name="lines">Sii file source code lines</param> /// <param name="start">Object initial line</param> /// <param name="end">Object last line</param> /// <returns>The parsed object</returns> public static Object ParseObject(string[] lines, int start, int end) { IDictionary <string, Attribute> attrs = new Dictionary <string, Attribute>(); IDictionary <string, Object> children = new Dictionary <string, Object>(); int objectMetaIdx = lines[start].Equals("{") ? start - 1 : start; string[] meta = lines[objectMetaIdx].Split(':'); string objName = meta.Length > 1 ? meta[1].Trim(' ', '{') : meta[0].Trim(' ', '{'); string clsName = meta.Length > 1 ? meta[0].Trim() : ""; for ( int i = start + (lines[start + 1].Equals("{") ? 2 : 1); i < end; i++ ) { string line = lines[i]; bool isObject = SiiTextParser.IsObjectBeginning(lines, i, ref i); if (isObject) { int objectStart = i; int objectEnd = SiiTextParser.GetObjectEndLineIndex(lines, objectStart); Object child = ParseObject(lines, objectStart, objectEnd); children.Add(child.Name, child); i += objectEnd - objectStart - 1; } else { if (!line.Equals("}")) { Attribute attr; (string attrName, string attrValue) = SiiTextParser.ParseAttribute(line); attr = AttributeDeserializer.ParseAttribute(attrName, attrValue); if (attr is ArrayItemAttribute) { AddArrayItem((ArrayItemAttribute)attr, attrs); } else { attrs.Add(attr.Name, attr); } } } } return(new Object(objName, clsName, children, attrs)); }
/// <summary> /// Read a Sii text file. /// </summary> /// <param name="stream">Stream containing the sii text data</param> /// <returns>The root Sii object representing the unit</returns> public async Task <Object> ReadFromText(Stream stream) { using (StreamReader sr = new StreamReader(stream)) { string content = await sr.ReadToEndAsync(); if (!content.StartsWith(SII_TEXT_UNIT_SIGNATURE)) // Not a valid text unit { throw new InvalidSiiFileException(); } content = SiiTextParser.SanitizeSource(content); string[] lines = SiiTextParser.SplitSourceToLines(content).ToArray(); lines = (await ProcessIncludes(lines)).ToArray(); return(ObjectDeserializer.ParseObject(lines, 0, lines.Length)); } }