| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 |
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- // Copyright (c) 2004-2005 Novell, Inc.
- //
- // Authors:
- // Duncan Mak [email protected]
- // Nick Drochak [email protected]
- // Paolo Molaro [email protected]
- // Peter Bartok [email protected]
- // Gert Driesen [email protected]
- // Olivier Dufour [email protected]
- // Gary Barnett [email protected]
- using System;
- using System.Collections;
- using System.Collections.Specialized;
- using System.ComponentModel;
- using System.ComponentModel.Design;
- using System.Globalization;
- using System.IO;
- using System.Resources;
- using System.Runtime.Serialization.Formatters.Binary;
- using System.Xml;
- using System.Reflection;
- using System.Drawing;
- using System.Runtime.Serialization;
- namespace System.Resources
- {
- #if INSIDE_SYSTEM_WEB
- internal
- #else
- public
- #endif
- class ResXResourceReader : IResourceReader, IDisposable
- {
- #region Local Variables
- private string fileName;
- private Stream stream;
- private TextReader reader;
- private OrderedDictionary hasht;
- private ITypeResolutionService typeresolver;
- private XmlTextReader xmlReader;
- private string basepath;
- private bool useResXDataNodes;
- private AssemblyName [] assemblyNames;
- private OrderedDictionary hashtm;
- #endregion // Local Variables
- #region Constructors & Destructor
- public ResXResourceReader (Stream stream)
- {
- if (stream == null)
- throw new ArgumentNullException ("stream");
- if (!stream.CanRead)
- throw new ArgumentException ("Stream was not readable.");
- this.stream = stream;
- }
- public ResXResourceReader (Stream stream, ITypeResolutionService typeResolver)
- : this (stream)
- {
- this.typeresolver = typeResolver;
- }
- public ResXResourceReader (string fileName)
- {
- this.fileName = fileName;
- }
- public ResXResourceReader (string fileName, ITypeResolutionService typeResolver)
- : this (fileName)
- {
- this.typeresolver = typeResolver;
- }
- public ResXResourceReader (TextReader reader)
- {
- this.reader = reader;
- }
- public ResXResourceReader (TextReader reader, ITypeResolutionService typeResolver)
- : this (reader)
- {
- this.typeresolver = typeResolver;
- }
- public ResXResourceReader (Stream stream, AssemblyName [] assemblyNames)
- : this (stream)
- {
- this.assemblyNames = assemblyNames;
- }
- public ResXResourceReader (string fileName, AssemblyName [] assemblyNames)
- : this (fileName)
- {
- this.assemblyNames = assemblyNames;
- }
- public ResXResourceReader (TextReader reader, AssemblyName [] assemblyNames)
- : this (reader)
- {
- this.assemblyNames = assemblyNames;
- }
- ~ResXResourceReader ()
- {
- Dispose (false);
- }
- #endregion // Constructors & Destructor
- public string BasePath {
- get { return basepath; }
- set { basepath = value; }
- }
- public bool UseResXDataNodes {
- get { return useResXDataNodes; }
- set {
- if (xmlReader != null)
- throw new InvalidOperationException ();
- useResXDataNodes = value;
- }
- }
- #region Private Methods
- private void LoadData ()
- {
- hasht = new OrderedDictionary ();
- hashtm = new OrderedDictionary ();
- if (fileName != null) {
- stream = File.OpenRead (fileName);
- }
- try {
- xmlReader = null;
- if (stream != null) {
- xmlReader = new XmlTextReader (stream);
- } else if (reader != null) {
- xmlReader = new XmlTextReader (reader);
- }
- if (xmlReader == null) {
- throw new InvalidOperationException ("ResourceReader is closed.");
- }
- xmlReader.WhitespaceHandling = WhitespaceHandling.None;
- ResXHeader header = new ResXHeader ();
- try {
- while (xmlReader.Read ()) {
- if (xmlReader.NodeType != XmlNodeType.Element)
- continue;
- switch (xmlReader.LocalName) {
- case "resheader":
- ParseHeaderNode (header);
- break;
- case "data":
- ParseDataNode (false);
- break;
- case "metadata":
- ParseDataNode (true);
- break;
- }
- }
- } catch (XmlException ex) {
- throw new ArgumentException ("Invalid ResX input.", ex);
- } catch (SerializationException ex) {
- throw ex;
- } catch (TargetInvocationException ex) {
- throw ex;
- } catch (Exception ex) {
- XmlException xex = new XmlException (ex.Message, ex,
- xmlReader.LineNumber, xmlReader.LinePosition);
- throw new ArgumentException ("Invalid ResX input.", xex);
- }
- header.Verify ();
- } finally {
- if (fileName != null) {
- stream.Close ();
- stream = null;
- }
- xmlReader = null;
- }
- }
- private void ParseHeaderNode (ResXHeader header)
- {
- string v = GetAttribute ("name");
- if (v == null)
- return;
- if (String.Compare (v, "resmimetype", true) == 0) {
- header.ResMimeType = GetHeaderValue ();
- } else if (String.Compare (v, "reader", true) == 0) {
- header.Reader = GetHeaderValue ();
- } else if (String.Compare (v, "version", true) == 0) {
- header.Version = GetHeaderValue ();
- } else if (String.Compare (v, "writer", true) == 0) {
- header.Writer = GetHeaderValue ();
- }
- }
- private string GetHeaderValue ()
- {
- string value = null;
- xmlReader.ReadStartElement ();
- if (xmlReader.NodeType == XmlNodeType.Element) {
- value = xmlReader.ReadElementString ();
- } else {
- value = xmlReader.Value.Trim ();
- }
- return value;
- }
- private string GetAttribute (string name)
- {
- if (!xmlReader.HasAttributes)
- return null;
- for (int i = 0; i < xmlReader.AttributeCount; i++) {
- xmlReader.MoveToAttribute (i);
- if (String.Compare (xmlReader.Name, name, true) == 0) {
- string v = xmlReader.Value;
- xmlReader.MoveToElement ();
- return v;
- }
- }
- xmlReader.MoveToElement ();
- return null;
- }
- private string GetDataValue (bool meta, out string comment)
- {
- string value = null;
- comment = null;
- while (xmlReader.Read ()) {
- if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.LocalName == (meta ? "metadata" : "data"))
- break;
- if (xmlReader.NodeType == XmlNodeType.Element) {
- if (xmlReader.Name.Equals ("value")) {
- xmlReader.WhitespaceHandling = WhitespaceHandling.Significant;
- value = xmlReader.ReadString ();
- xmlReader.WhitespaceHandling = WhitespaceHandling.None;
- } else if (xmlReader.Name.Equals ("comment")) {
- xmlReader.WhitespaceHandling = WhitespaceHandling.Significant;
- comment = xmlReader.ReadString ();
- xmlReader.WhitespaceHandling = WhitespaceHandling.None;
- if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.LocalName == (meta ? "metadata" : "data"))
- break;
- }
- }
- else
- value = xmlReader.Value.Trim ();
- }
- return value;
- }
- private void ParseDataNode (bool meta)
- {
- OrderedDictionary hashtable = ((meta && ! useResXDataNodes) ? hashtm : hasht);
- Point pos = new Point (xmlReader.LineNumber, xmlReader.LinePosition);
- string name = GetAttribute ("name");
- string type_name = GetAttribute ("type");
- string mime_type = GetAttribute ("mimetype");
- string comment = null;
- string value = GetDataValue (meta, out comment);
- ResXDataNode node = new ResXDataNode (name, mime_type, type_name, value, comment, pos, BasePath);
- if (useResXDataNodes) {
- hashtable [name] = node;
- return;
- }
- if (name == null)
- throw new ArgumentException (string.Format (CultureInfo.CurrentCulture,
- "Could not find a name for a resource. The resource value was '{0}'.",
- node.GetValue ((AssemblyName []) null).ToString()));
- // useResXDataNodes is false, add to dictionary of values
- if (assemblyNames != null) {
- try {
- hashtable [name] = node.GetValue (assemblyNames);
- } catch (TypeLoadException ex) {
- // different error messages depending on type of resource, hacky solution
- if (node.handler is TypeConverterFromResXHandler)
- hashtable [name] = null;
- else
- throw ex;
- }
- } else { // there is a typeresolver or its null
- try {
- hashtable [name] = node.GetValue (typeresolver);
- } catch (TypeLoadException ex) {
- if (node.handler is TypeConverterFromResXHandler)
- hashtable [name] = null;
- else
- throw ex;
- }
- }
- }
- #endregion // Private Methods
- #region Public Methods
- public void Close ()
- {
- if (reader != null) {
- reader.Close ();
- reader = null;
- }
- }
- public IDictionaryEnumerator GetEnumerator ()
- {
- if (hasht == null) {
- LoadData ();
- }
- return hasht.GetEnumerator ();
- }
- IEnumerator IEnumerable.GetEnumerator ()
- {
- return ((IResourceReader) this).GetEnumerator ();
- }
- void IDisposable.Dispose ()
- {
- Dispose (true);
- GC.SuppressFinalize (this);
- }
- protected virtual void Dispose (bool disposing)
- {
- if (disposing) {
- Close ();
- }
- }
- public static ResXResourceReader FromFileContents (string fileContents)
- {
- return new ResXResourceReader (new StringReader (fileContents));
- }
- public static ResXResourceReader FromFileContents (string fileContents, ITypeResolutionService typeResolver)
- {
- return new ResXResourceReader (new StringReader (fileContents), typeResolver);
- }
- public static ResXResourceReader FromFileContents (string fileContents, AssemblyName [] assemblyNames)
- {
- return new ResXResourceReader (new StringReader (fileContents), assemblyNames);
- }
- public IDictionaryEnumerator GetMetadataEnumerator ()
- {
- if (hashtm == null)
- LoadData ();
- return hashtm.GetEnumerator ();
- }
- #endregion // Public Methods
- #region Internal Classes
- private class ResXHeader
- {
- private string resMimeType;
- private string reader;
- private string version;
- private string writer;
- public string ResMimeType
- {
- get { return resMimeType; }
- set { resMimeType = value; }
- }
- public string Reader {
- get { return reader; }
- set { reader = value; }
- }
- public string Version {
- get { return version; }
- set { version = value; }
- }
- public string Writer {
- get { return writer; }
- set { writer = value; }
- }
- public void Verify ()
- {
- if (!IsValid)
- throw new ArgumentException ("Invalid ResX input. Could "
- + "not find valid \"resheader\" tags for the ResX "
- + "reader & writer type names.");
- }
- public bool IsValid {
- get {
- if (string.Compare (ResMimeType, ResXResourceWriter.ResMimeType) != 0)
- return false;
- if (Reader == null || Writer == null)
- return false;
- string readerType = Reader.Split (',') [0].Trim ();
- if (readerType != typeof (ResXResourceReader).FullName)
- return false;
- string writerType = Writer.Split (',') [0].Trim ();
- if (writerType != typeof (ResXResourceWriter).FullName)
- return false;
- return true;
- }
- }
- }
- #endregion
- }
- }
|