/// <summary> /// Writes an EntitiesFile object to a file /// </summary> /// <param name="entitiesFile">EntitiesFile object</param> /// <param name="path">destination path</param> public static void WriteEntitiesFile(EntitiesFile entitiesFile, string path) { using (var streamWriter = new StreamWriter(path, false)) { streamWriter.NewLine = ""; streamWriter.WriteLine(GetEntitiesFileHeaderString(entitiesFile)); if (entitiesFile.Properties != null && entitiesFile.Properties.Count != 0) { streamWriter.WriteLine(GetPropertiesSectionString(entitiesFile.Properties)); } for (int i = 0; i < entitiesFile.Entities.Count; i++) { streamWriter.WriteLine(GetEntityString(entitiesFile.Entities[i])); if (i != entitiesFile.Entities.Count - 1) { streamWriter.WriteLine("\n"); } } streamWriter.Close(); } }
/// <summary> /// Builds the header string of the entities file /// </summary> /// <param name="entitiesFile">EntitiesFile object</param> /// <returns>the header string of the entities file</returns> internal static string GetEntitiesFileHeaderString(EntitiesFile entitiesFile) { StringBuilder header = new StringBuilder(); if (!string.IsNullOrEmpty(entitiesFile.Version)) { header.Append("Version ").Append(entitiesFile.Version).Append("\n"); } if (!string.IsNullOrEmpty(entitiesFile.HierarchyVersion)) { header.Append("HierarchyVersion ").Append(entitiesFile.HierarchyVersion).Append("\n"); } return(header.ToString()); }
/// <summary> /// Parses the given entities file into an EntitiesFile object /// </summary> /// <param name="entitiesFilePath">path to the entities file</param> /// <returns>an EntitiesFile object with the parsed data from the entities file</returns> public EntitiesFileParseResult Parse(string entitiesFilePath) { if (!File.Exists(entitiesFilePath)) { throw new FileNotFoundException(string.Format("Entities file not found in path: {0}", entitiesFilePath)); } Warnings = new List <string>(); Errors = new List <string>(); EntitiesFile entitiesFile = new EntitiesFile() { Version = string.Empty, HierarchyVersion = string.Empty }; int currentLineNumber = 0; using (FileStream fs = File.Open(entitiesFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (BufferedStream bs = new BufferedStream(fs)) { using (StreamReader sr = new StreamReader(bs)) { string line = string.Empty; bool nextEntityError = false; int openingBracketCount = 0; int closingBracketCount = 0; List <Entity> entities = new List <Entity>(); StringBuilder currentEntity = new StringBuilder(); // Get whole entity blocks to pass them to the entity parser while ((line = sr.ReadLine()) != null) { // Remove comments from lines line = RemoveComments(line, "//"); currentLineNumber++; line = line.Trim(); if (string.IsNullOrEmpty(line)) { continue; } // Try to parse the version headers first if we don't have them yet and // if we haven't found any entity block yet if (entitiesFile.Version == string.Empty || entitiesFile.HierarchyVersion == string.Empty && openingBracketCount == 0) { string[] versionHeaderPart = line.Split(' '); if (versionHeaderPart.Length == 2 && versionHeaderPart[0].Equals("Version")) { entitiesFile.Version = versionHeaderPart[1]; continue; } else if (versionHeaderPart.Length == 2 && versionHeaderPart[0].Equals("HierarchyVersion")) { entitiesFile.HierarchyVersion = versionHeaderPart[1]; continue; } } // Look for the properties section if (openingBracketCount == 0 && entitiesFile.Properties == null && (line.Equals("properties {") || line.Equals("properties{"))) { // Parse the properties entitiesFile.Properties = new List <EntityProperty>(); while ((line = sr.ReadLine()) != null && !line.Trim().Equals("}")) { try { currentLineNumber++; entitiesFile.Properties.Add(ParseEntityProperty(line, ref currentLineNumber, true)); } catch (FormatException) { throw; } } // Closing bracket currentLineNumber++; // Read the next line after the closing bracket if ((line = sr.ReadLine()) == null) { break; } // Next line currentLineNumber++; } // Look for entities if (openingBracketCount == 0) { if (!line.Equals("entity {") && !line.Equals("entity{")) { if (line.Equals("entity")) { Errors.Add(string.Format("Line {0}: missing '{{'", currentLineNumber)); } else { Errors.Add(string.Format("Line {0}: unexpected '{1}", currentLineNumber, line)); } continue; } // Found an entity here, add the first line and look for the lines in its block currentEntity.Append(line).Append("\n"); openingBracketCount++; closingBracketCount = 0; continue; } // We are in an entity block here, get everything until we find the closing bracket if (line[line.Length - 1] == '{') { openingBracketCount++; } if (line[line.Length - 1] == '}') { closingBracketCount++; } // If we find another entity block, check for the closing bracket of our current entity // and opening bracket for the next entity, then continue with it // If not, just continue adding current entity block lines until we hit another entity if (!line.Equals("entity {") && !line.Equals("entity{")) { if (line.Equals("entity")) { Errors.Add(string.Format("Line {0}: missing '{{'", currentLineNumber)); nextEntityError = true; } else { if (openingBracketCount != closingBracketCount) { currentEntity.Append(line).Append("\n"); continue; } else { currentEntity.Append(line); // All OK, push current entity to the entity parser // and continue searching for more try { Entity parsedEntity = ParseEntity(currentEntity.ToString(), ref currentLineNumber); if (parsedEntity != null && parsedEntity.EntityDef != null) { entities.Add(parsedEntity); } } catch (FormatException) { throw; } openingBracketCount = 0; closingBracketCount = 0; currentEntity.Clear(); continue; } } } // We hit another entity at this point // Check for the closing bracket of this current entity // Substract 1 from the opening brackets count to not take // the next entity opening bracket into account if ((openingBracketCount - 1 != closingBracketCount) || (nextEntityError && (openingBracketCount != closingBracketCount))) { Errors.Add(string.Format("Line {0}: missing '}}'", currentLineNumber)); nextEntityError = false; } // All OK, push current entity to the entity parser // and continue with the next one try { // Don't take into account the next entity line currentLineNumber--; // Remove last new line character currentEntity.Remove(currentEntity.Length - 1, 1); Entity parsedEntity = ParseEntity(currentEntity.ToString(), ref currentLineNumber); if (parsedEntity != null && parsedEntity.EntityDef != null) { entities.Add(parsedEntity); } } catch (FormatException) { throw; } currentLineNumber++; openingBracketCount = 1; closingBracketCount = 0; currentEntity.Clear(); currentEntity.Append(line).Append("\n"); } entitiesFile.Entities = entities; } } } return(new EntitiesFileParseResult() { Errors = Errors.ToArray(), Warnings = Warnings.ToArray(), EntitiesFile = entitiesFile }); }