/// <summary> /// Loads a package from the specified stream and returns it as a RantPackage object. /// </summary> /// <param name="source">The stream to load the package data from.</param> /// <returns></returns> public static RantPackage Load(Stream source) { using (var reader = new EasyReader(source)) { var magic = Encoding.ASCII.GetString(reader.ReadBytes(4)); if (magic == OLD_MAGIC) { return(LoadOldPackage(reader)); } if (magic != MAGIC) { throw new InvalidDataException("File is corrupt."); } var package = new RantPackage(); var version = reader.ReadUInt32(); if (version != PACKAGE_VERSION) { throw new InvalidDataException("Invalid package version: " + version); } var compress = reader.ReadBoolean(); var size = reader.ReadInt32(); var data = reader.ReadBytes(size); if (compress) { data = EasyCompressor.Decompress(data); } var doc = BsonDocument.Read(data); var info = doc["info"]; if (info == null) { throw new InvalidDataException("Metadata is missing from package."); } package.Title = info["title"]; package.ID = info["id"]; package.Version = RantPackageVersion.Parse(info["version"]); package.Description = info["description"]; package.Authors = (string[])info["authors"]; package.Tags = (string[])info["tags"]; var deps = info["dependencies"]; if (deps != null && deps.IsArray) { for (int i = 0; i < deps.Count; i++) { var dep = deps[i]; var depId = dep["id"].Value; var depVersion = dep["version"].Value; bool depAllowNewer = (bool)dep["allow-newer"].Value; package.AddDependency(new RantPackageDependency(depId.ToString(), depVersion.ToString()) { AllowNewer = depAllowNewer }); } } var patterns = doc["patterns"]; if (patterns != null) { var names = patterns.Keys; foreach (string name in names) { package.AddPattern(new RantPattern(name, RantPatternOrigin.File, patterns[name])); } } var tables = doc["tables"]; if (tables != null) { var names = tables.Keys; foreach (string name in names) { var table = tables[name]; string tableName = table["name"]; string[] tableSubs = (string[])table["subs"]; string[] hiddenClasses = (string[])table["hidden"]; var entries = new List <RantDictionaryEntry>(); var entryList = table["entries"]; for (var i = 0; i < entryList.Count; i++) { var loadedEntry = entryList[i]; int weight = 1; if (loadedEntry.HasKey("weight")) { weight = (int)loadedEntry["weight"].Value; } string[] requiredClasses = (string[])loadedEntry["classes"]; string[] optionalClasses = (string[])loadedEntry["optional_classes"]; var terms = new List <RantDictionaryTerm>(); var termList = loadedEntry["terms"]; for (var j = 0; j < termList.Count; j++) { var t = new RantDictionaryTerm(termList[j]["value"], termList[j]["pron"]); terms.Add(t); } var entry = new RantDictionaryEntry( terms.ToArray(), requiredClasses.Concat(optionalClasses.Select(x => x + "?")), weight ); entries.Add(entry); } var rantTable = new RantDictionaryTable( tableName, tableSubs, entries, hiddenClasses ); package.AddTable(rantTable); } } return(package); } }
/// <summary> /// Saves the package to the specified file path. /// </summary> /// <param name="path">The path to the file to create.</param> public void Save( string path, bool compress = true, BsonStringTableMode stringTableMode = BsonStringTableMode.None) { if (String.IsNullOrEmpty(Path.GetExtension(path))) { path += ".rantpkg"; } using (var writer = new EasyWriter(File.Create(path))) { var doc = new BsonDocument(stringTableMode); var info = doc.Top["info"] = new BsonItem(); info["title"] = new BsonItem(_title); info["id"] = new BsonItem(_id); info["description"] = new BsonItem(Description); info["tags"] = new BsonItem(Tags); info["version"] = new BsonItem(Version.ToString()); info["authors"] = new BsonItem(Authors); info["dependencies"] = new BsonItem(_dependencies.Select(dep => { var depObj = new BsonItem(); depObj["id"] = dep.ID; depObj["version"] = dep.Version.ToString(); depObj["allow-newer"] = dep.AllowNewer; return(depObj); }).ToArray()); var patterns = doc.Top["patterns"] = new BsonItem(); if (_patterns != null) { foreach (var pattern in _patterns) { patterns[pattern.Name] = new BsonItem(pattern.Code); } } var tables = doc.Top["tables"] = new BsonItem(); if (_tables != null) { foreach (var table in _tables) { var t = tables[table.Name] = new BsonItem(); t["name"] = new BsonItem(table.Name); t["subs"] = new BsonItem(table.Subtypes); t["language"] = new BsonItem(table.Language); t["hidden"] = new BsonItem(table.HiddenClasses.ToArray()); t["hints"] = new BsonItem(0); var entries = new List <BsonItem>(); foreach (var entry in table.GetEntries()) { var e = new BsonItem(); if (entry.Weight != 1) { e["weight"] = new BsonItem(entry.Weight); } var requiredClasses = entry.GetRequiredClasses().ToArray(); if (requiredClasses.Length > 0) { e["classes"] = new BsonItem(requiredClasses); } var optionalClasses = entry.GetOptionalClasses().ToArray(); if (optionalClasses.Length > 0) { e["optional_classes"] = new BsonItem(); } var terms = new List <BsonItem>(); foreach (var term in entry.Terms) { var et = new BsonItem(); et["value"] = new BsonItem(term.Value); if (term.Pronunciation != "") { et["pron"] = new BsonItem(term.Pronunciation); } terms.Add(et); } e["terms"] = new BsonItem(terms.ToArray()); entries.Add(e); } t["entries"] = new BsonItem(entries.ToArray()); } } var data = doc.ToByteArray(stringTableMode != BsonStringTableMode.None); if (compress) { data = EasyCompressor.Compress(data); } writer.Write(Encoding.ASCII.GetBytes("RANT")); writer.Write((uint)2); writer.Write(compress); writer.Write(data.Length); writer.Write(data); } }