using System; using System.Xml; using System.Collections; namespace TeamXBMC.TranslatorCore { /// /// Represents a xml language file of XBMC /// /// public class StringArray : ICollection { private ArrayList strings=new ArrayList(); private Hashtable stringsMap=new Hashtable(); private double version=0.0; #region Constructors public StringArray() { } #endregion #region Language file procressing /// /// Loads a language file by filename /// public void Load(string filename) { XmlTextReader reader=null; try { reader=new XmlTextReader(filename); XmlDocument doc=new XmlDocument(); doc.Load(reader); foreach (XmlNode node in doc) { if (node.NodeType==XmlNodeType.Comment && node.InnerText.IndexOf("$Revision")>-1) { string comment=node.InnerText; int startPos=comment.IndexOf("$Revision")+10; int endPos=comment.IndexOf("$", startPos); if (endPos>startPos) { string str=comment.Substring(startPos, endPos-startPos); version=Convert.ToDouble(str, System.Globalization.CultureInfo.InvariantCulture); } break; } } XmlNode root=doc.DocumentElement.SelectSingleNode("/strings"); if (root==null) throw new TranslatorException(filename+" is not a language file."); XmlNodeList list=doc.DocumentElement.SelectNodes("/strings/string"); if (list.Count>0) { foreach (XmlNode node in list) { StringItem item=new StringItem(); item.LoadFromXml((XmlElement)node); Add(item); } strings.Sort(); } } catch(Exception e) { throw new TranslatorException("Error loading "+filename, e); } finally { if (reader!=null) reader.Close(); } } /// /// Saves a language file by filename /// public bool Save(string filename) { return Save(filename, null); } /// /// Saves a language file by filename, with additional comments /// public bool Save(string filename, string[] comments) { XmlTextWriter writer=null; try { XmlDocument doc=new XmlDocument(); doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", "yes")); if (comments!=null) { foreach(string comment in comments) { doc.AppendChild(doc.CreateComment(comment)); } } XmlElement root=doc.CreateElement("strings"); doc.AppendChild(root); foreach (StringItem item in this) { XmlElement element=doc.CreateElement("string"); root.AppendChild(element); item.SaveToXml(ref element); } writer=new XmlTextWriter(filename, System.Text.Encoding.UTF8); writer.Formatting=Formatting.Indented; doc.Save(writer); } catch(Exception e) { throw new TranslatorException("Error saving "+filename, e); } finally { if (writer!=null) writer.Close(); } return true; } #endregion #region Array methods /// /// Add a StringItem to the StringArray /// public void Add(StringItem item) { try { stringsMap.Add(item.Id, item); } catch (ArgumentException e) { throw new TranslatorException("The string with the id " + item.Id.ToString() + " appears more then once in this file.", e); } strings.Add(item); } /// /// Remove all StringItems from the StringArray /// public void Clear() { strings.Clear(); stringsMap.Clear(); } /// /// Sort the StringArray by StringItem id /// public void Sort() { strings.Sort(); } /// /// Returns a string with a certain id /// public bool GetStringById(long id, ref StringItem item) { if (!stringsMap.Contains(id)) { item=null; return false; } item=(StringItem)stringsMap[id]; return true; } /// /// Returns a StringArray with all string not in /// arr. /// public StringArray GetStringsNotIn(StringArray arr) { StringArray ret=new StringArray(); foreach (StringItem item in strings) { if (item.Id!=6) // "XBMC SVN" { StringItem stringItem=null; arr.GetStringById(item.Id, ref stringItem); if (stringItem==null) ret.Add(item); } } return ret; } /// /// Returns the ids of all changed strings /// of arr. /// public long[] GetStringsChangedIn(StringArray arr) { ArrayList ret=new ArrayList(); foreach (StringItem item in strings) { if (item.Id!=6) // "XBMC SVN" { StringItem stringItem=null; arr.GetStringById(item.Id, ref stringItem); if (stringItem!=null && stringItem.Text!=item.Text) ret.Add(item.Id); } } return (long[])ret.ToArray(typeof(long)); } #endregion #region Properties /// /// Returns the version of the strings file /// public double Version { get { return version; } } #endregion #region ICollection Members public void CopyTo(Array array, int index) { strings.CopyTo(array, index); } public int Count { get{return strings.Count;} } public object SyncRoot { get{return this;} } public bool IsSynchronized { get{return false;} } #endregion #region IEnumerable Members public IEnumerator GetEnumerator() { return strings.GetEnumerator(); } #endregion } }