ResXResourceWriter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / Resources / ResXResourceWriter.cs / 1305376 / ResXResourceWriter.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

#if SYSTEM_WEB  // See DevDiv 9030 
namespace System.PrivateResources { 
#else
namespace System.Resources { 
#endif

    using System.Diagnostics;
    using System.Reflection; 
    using System;
    using System.Windows.Forms; 
    using Microsoft.Win32; 
    using System.Drawing;
    using System.IO; 
    using System.Text;
    using System.ComponentModel;
    using System.Collections;
    using System.Resources; 
    using System.Xml;
    using System.Runtime.Serialization; 
    using System.Diagnostics.CodeAnalysis; 
#if SYSTEM_WEB
    using System.Web;   // This is needed to access the SR resource strings 
#endif

    /// 
    ///  
    ///     ResX resource writer. See the text in "ResourceSchema" for more
    ///     information. 
    ///  
    [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.InheritanceDemand, Name="FullTrust")]
    [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name="FullTrust")] 
#if SYSTEM_WEB
    internal class ResXResourceWriter : IResourceWriter {
#else
    public class ResXResourceWriter : IResourceWriter { 
#endif
        internal const string TypeStr = "type"; 
        internal const string NameStr = "name"; 
        internal const string DataStr = "data";
        internal const string MetadataStr = "metadata"; 
        internal const string MimeTypeStr = "mimetype";
        internal const string ValueStr = "value";
        internal const string ResHeaderStr = "resheader";
        internal const string VersionStr = "version"; 
        internal const string ResMimeTypeStr = "resmimetype";
        internal const string ReaderStr = "reader"; 
        internal const string WriterStr = "writer"; 
        internal const string CommentStr = "comment";
        internal const string AssemblyStr ="assembly"; 
        internal const string AliasStr= "alias" ;

        private Hashtable cachedAliases;
 
        private static TraceSwitch ResValueProviderSwitch = new TraceSwitch("ResX", "Debug the resource value provider");
 
        // 

 



 

        internal static readonly string Beta2CompatSerializedObjectMimeType = "text/microsoft-urt/psuedoml-serialized/base64"; 
 
        // These two "compat" mimetypes are here. In Beta 2 and RTM we used the term "URT"
        // internally to refer to parts of the .NET Framework. Since these references 
        // will be in Beta 2 ResX files, and RTM ResX files for customers that had
        // early access to releases, we don't want to break that. We will read
        // and parse these types correctly in version 1.0, but will always
        // write out the new version. So, opening and editing a ResX file in VS will 
        // update it to the new types.
        // 
        internal static readonly string CompatBinSerializedObjectMimeType = "text/microsoft-urt/binary-serialized/base64"; 
        internal static readonly string CompatSoapSerializedObjectMimeType = "text/microsoft-urt/soap-serialized/base64";
 
        /// 
        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public static readonly string BinSerializedObjectMimeType = "application/x-microsoft.net.object.binary.base64"; 
        ///  
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public static readonly string SoapSerializedObjectMimeType = "application/x-microsoft.net.object.soap.base64";
        ///  
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public static readonly string DefaultSerializedObjectMimeType = BinSerializedObjectMimeType; 
        /// 
        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public static readonly string ByteArraySerializedObjectMimeType = "application/x-microsoft.net.object.bytearray.base64"; 
        ///  
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public static readonly string ResMimeType = "text/microsoft-resx";
        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public static readonly string Version = "2.0";
 
        /// 
        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public static readonly string ResourceSchema = @" 
    
    
         
        
             
                 
                    
                         
                            
                            
                            
                             
                            
                             
                             
                        
                     
                    
                      
                        
                         
                      
                     
                     
                        
                             
                                
                                
                            
                             
                            
                             
                             
                        
                     
                    
                        
                            
                                 
                            
                             
                         
                    
                 
            
        
        
        "; 

        IFormatter binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter (); 
        string fileName; 
        Stream stream;
        TextWriter textWriter; 
        XmlTextWriter xmlTextWriter;
        string basePath;

        bool hasBeenSaved; 
        bool initialized;
 
        private Func typeNameConverter; // no public property to be consistent with ResXDataNode class. 

        ///  
        /// 
        ///     Base Path for ResXFileRefs.
        /// 
        public string BasePath { 
            get {
                return basePath; 
            } 
            set {
                basePath = value; 
            }
        }

        ///  
        /// 
        ///     Creates a new ResXResourceWriter that will write to the specified file. 
        ///  
        public ResXResourceWriter(string fileName) {
            this.fileName = fileName; 
        }
        public ResXResourceWriter(string fileName, Func typeNameConverter) {
            this.fileName = fileName;
            this.typeNameConverter = typeNameConverter; 
        }
 
        ///  
        /// 
        ///     Creates a new ResXResourceWriter that will write to the specified stream. 
        /// 
        public ResXResourceWriter(Stream stream) {
            this.stream = stream;
        } 
        public ResXResourceWriter(Stream stream, Func typeNameConverter) {
            this.stream = stream; 
            this.typeNameConverter = typeNameConverter; 
        }
 
        /// 
        /// 
        ///     Creates a new ResXResourceWriter that will write to the specified TextWriter.
        ///  
        public ResXResourceWriter(TextWriter textWriter) {
            this.textWriter = textWriter; 
        } 
        public ResXResourceWriter(TextWriter textWriter, Func typeNameConverter) {
            this.textWriter = textWriter; 
            this.typeNameConverter = typeNameConverter;
        }

        ///  
        ~ResXResourceWriter() {
            Dispose(false); 
        } 

        private void InitializeWriter() { 
            if (xmlTextWriter == null) {
                //

                bool writeHeaderHack = false; 

                if (textWriter != null) { 
                    textWriter.WriteLine(""); 
                    writeHeaderHack = true;
 
                    xmlTextWriter = new XmlTextWriter(textWriter);
                }
                else if (stream != null) {
                    xmlTextWriter = new XmlTextWriter(stream, System.Text.Encoding.UTF8); 
                }
                else { 
                    Debug.Assert(fileName != null, "Nothing to output to"); 
                    xmlTextWriter = new XmlTextWriter(fileName, System.Text.Encoding.UTF8);
                } 
                xmlTextWriter.Formatting = Formatting.Indented;
                xmlTextWriter.Indentation = 2;

                if (!writeHeaderHack) { 
                    xmlTextWriter.WriteStartDocument(); // writes 
                } 
            } 
            else {
                xmlTextWriter.WriteStartDocument(); 
            }

            xmlTextWriter.WriteStartElement("root");
            XmlTextReader reader = new XmlTextReader(new StringReader(ResourceSchema)); 
            reader.WhitespaceHandling = WhitespaceHandling.None;
            xmlTextWriter.WriteNode(reader, true); 
 
            xmlTextWriter.WriteStartElement(ResHeaderStr); {
                xmlTextWriter.WriteAttributeString(NameStr, ResMimeTypeStr); 
                xmlTextWriter.WriteStartElement(ValueStr); {
                    xmlTextWriter.WriteString(ResMimeType);
                }
                xmlTextWriter.WriteEndElement(); 
            }
            xmlTextWriter.WriteEndElement(); 
            xmlTextWriter.WriteStartElement(ResHeaderStr); { 
                xmlTextWriter.WriteAttributeString(NameStr, VersionStr);
                xmlTextWriter.WriteStartElement(ValueStr); { 
                    xmlTextWriter.WriteString(Version);
                }
                xmlTextWriter.WriteEndElement();
            } 
            xmlTextWriter.WriteEndElement();
            xmlTextWriter.WriteStartElement(ResHeaderStr); { 
                xmlTextWriter.WriteAttributeString(NameStr, ReaderStr); 
                xmlTextWriter.WriteStartElement(ValueStr); {
                    xmlTextWriter.WriteString(MultitargetUtil.GetAssemblyQualifiedName(typeof(ResXResourceReader), this.typeNameConverter)); 
                }
                xmlTextWriter.WriteEndElement();
            }
            xmlTextWriter.WriteEndElement(); 
            xmlTextWriter.WriteStartElement(ResHeaderStr); {
                xmlTextWriter.WriteAttributeString(NameStr, WriterStr); 
                xmlTextWriter.WriteStartElement(ValueStr); { 
                    xmlTextWriter.WriteString(MultitargetUtil.GetAssemblyQualifiedName(typeof(ResXResourceWriter), this.typeNameConverter));
                } 
                xmlTextWriter.WriteEndElement();
            }
            xmlTextWriter.WriteEndElement();
 
            initialized = true;
        } 
 
        private XmlWriter Writer {
            get { 
                if (!initialized) {
                    InitializeWriter();
                }
                return xmlTextWriter; 
            }
        } 
 
        /// 
        ///  
        ///    Adds aliases to the resource file...
        /// 
        public virtual void AddAlias(string aliasName, AssemblyName assemblyName) {
           if (assemblyName == null) { 
               throw new ArgumentNullException("assemblyName");
           } 
 
           if (cachedAliases == null) {
               cachedAliases = new Hashtable(); 
           }

           cachedAliases[assemblyName.FullName] = aliasName;
       } 

 
        ///  
        /// 
        ///    Adds the given value to the collection of metadata.  These name/value pairs 
        ///    will be emitted to the  elements in the .resx file.
        /// 
        public void AddMetadata(string name, byte[] value) {
            AddDataRow(MetadataStr, name, value); 
        }
 
        ///  
        /// 
        ///    Adds the given value to the collection of metadata.  These name/value pairs 
        ///    will be emitted to the  elements in the .resx file.
        /// 
        public void AddMetadata(string name, string value) {
            AddDataRow(MetadataStr, name, value); 
        }
 
        ///  
        /// 
        ///    Adds the given value to the collection of metadata.  These name/value pairs 
        ///    will be emitted to the  elements in the .resx file.
        /// 
        public void AddMetadata(string name, object value) {
            AddDataRow(MetadataStr, name, value); 
        }
 
        ///  
        /// 
        ///     Adds a blob resource to the resources. 
        /// 
        // NOTE: Part of IResourceWriter - not protected by class level LinkDemand.
        public void AddResource(string name, byte[] value) {
            AddDataRow(DataStr, name, value); 
        }
 
        ///  
        /// 
        ///     Adds a resource to the resources. If the resource is a string, 
        ///     it will be saved that way, otherwise it will be serialized
        ///     and stored as in binary.
        /// 
        // NOTE: Part of IResourceWriter - not protected by class level LinkDemand. 
        public void AddResource(string name, object value) {
            if (value is ResXDataNode) { 
                AddResource((ResXDataNode)value); 
            }
            else { 
                AddDataRow(DataStr, name, value);
            }
        }
 
        /// 
        ///  
        ///     Adds a string resource to the resources. 
        /// 
        // NOTE: Part of IResourceWriter - not protected by class level LinkDemand. 
        public void AddResource(string name, string value) {
            AddDataRow(DataStr, name, value);
        }
 
         /// 
        ///  
        ///     Adds a string resource to the resources. 
        /// 
        public void AddResource(ResXDataNode node) { 
            // we're modifying the node as we're adding it to the resxwriter
            // this is BAD, so we clone it. adding it to a writer doesnt change it
            // we're messing with a copy
            ResXDataNode nodeClone = node.DeepClone(); 

            ResXFileRef fileRef = nodeClone.FileRef; 
            string modifiedBasePath = BasePath; 

            if (!String.IsNullOrEmpty(modifiedBasePath)) { 
                if (!(modifiedBasePath.EndsWith("\\")))
                {
                    modifiedBasePath += "\\";
                } 
                if (fileRef != null) {
                    fileRef.MakeFilePathRelative(modifiedBasePath); 
                } 
            }
            DataNodeInfo info = nodeClone.GetDataNodeInfo(); 
            AddDataRow(DataStr, info.Name, info.ValueData, info.TypeName, info.MimeType, info.Comment);
        }

        ///  
        ///     Adds a blob resource to the resources.
        ///  
        private void AddDataRow(string elementName, string name, byte[] value) { 
            AddDataRow(elementName, name, ToBase64WrappedString(value), TypeNameWithAssembly(typeof(byte[])), null, null);
        } 

        /// 
        ///     Adds a resource to the resources. If the resource is a string,
        ///     it will be saved that way, otherwise it will be serialized 
        ///     and stored as in binary.
        ///  
        private void AddDataRow(string elementName, string name, object value) { 
            Debug.WriteLineIf(ResValueProviderSwitch.TraceVerbose, "  resx: adding resource " + name);
            if (value is string) { 
                AddDataRow(elementName, name, (string)value);
            }
            else if (value is byte[]) {
                AddDataRow(elementName, name, (byte[])value); 
            }
            else if(value is ResXFileRef) { 
                ResXFileRef fileRef = (ResXFileRef)value; 
                ResXDataNode node = new ResXDataNode(name, fileRef, this.typeNameConverter);
                if (fileRef != null) { 
                    fileRef.MakeFilePathRelative(BasePath);
                }
                DataNodeInfo info = node.GetDataNodeInfo();
                AddDataRow(elementName, info.Name, info.ValueData, info.TypeName, info.MimeType, info.Comment); 
            } else {
                ResXDataNode node = new ResXDataNode(name, value, this.typeNameConverter); 
                DataNodeInfo info = node.GetDataNodeInfo(); 
                AddDataRow(elementName, info.Name, info.ValueData, info.TypeName, info.MimeType, info.Comment);
            } 
        }

        /// 
        ///     Adds a string resource to the resources. 
        /// 
        private void AddDataRow(string elementName, string name, string value) { 
            if(value == null) { 
                // if it's a null string, set it here as a resxnullref
                AddDataRow(elementName, name, value, MultitargetUtil.GetAssemblyQualifiedName(typeof(ResXNullRef), this.typeNameConverter), null, null); 
            } else {
                AddDataRow(elementName, name, value, null, null, null);
            }
        } 

        ///  
        ///     Adds a new row to the Resources table. This helper is used because 
        ///     we want to always late bind to the columns for greater flexibility.
        ///  
        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        private void AddDataRow(string elementName, string name, string value, string type, string mimeType, string comment) {
            if (hasBeenSaved)
                throw new InvalidOperationException(SR.GetString(SR.ResXResourceWriterSaved)); 

            string alias = null; 
            if (!string.IsNullOrEmpty(type) && elementName == DataStr) 
            {
                string assemblyName = GetFullName(type); 
                if(string.IsNullOrEmpty(assemblyName)) {
                    try {
                        Type typeObject = Type.GetType(type);
                        if(typeObject == typeof(string)) { 
                            type = null;
                        } else if(typeObject != null) { 
                            assemblyName = GetFullName(MultitargetUtil.GetAssemblyQualifiedName(typeObject, this.typeNameConverter)); 
                            alias = GetAliasFromName(new AssemblyName(assemblyName));
                        } 
                    } catch {
                    }
                } else {
                    alias = GetAliasFromName(new AssemblyName(GetFullName(type))); 
                }
                //AddAssemblyRow(AssemblyStr, alias, GetFullName(type)); 
            } 

            Writer.WriteStartElement(elementName); { 
                Writer.WriteAttributeString(NameStr, name);

                if (!string.IsNullOrEmpty(alias) && !string.IsNullOrEmpty(type) && elementName == DataStr) {
                     // CHANGE: we still output version information. This might have 
                    // to change in 3.2
                    string typeName = GetTypeName(type); 
                    string typeValue = typeName + ", " + alias; 
                    Writer.WriteAttributeString(TypeStr, typeValue);
                } 
                else {
                     if (type != null)
                     {
                        Writer.WriteAttributeString(TypeStr, type); 
                     }
                } 
 
                if (mimeType != null) {
                    Writer.WriteAttributeString(MimeTypeStr, mimeType); 
                }

                if((type == null && mimeType == null) || (type != null && type.StartsWith("System.Char", StringComparison.Ordinal))) {
                    Writer.WriteAttributeString("xml", "space", null, "preserve"); 
                }
 
                Writer.WriteStartElement(ValueStr); { 
                    if(!string.IsNullOrEmpty(value)) {
                        Writer.WriteString(value); 
                    }
                }
                Writer.WriteEndElement();
                if(!string.IsNullOrEmpty(comment)) { 
                    Writer.WriteStartElement(CommentStr); {
                        Writer.WriteString(comment); 
                    } 
                    Writer.WriteEndElement();
                } 
            }
            Writer.WriteEndElement();
        }
 

        private void AddAssemblyRow(string elementName, string alias, string name) 
        { 

            Writer.WriteStartElement(elementName); { 
                if (!string.IsNullOrEmpty(alias)) {
                      Writer.WriteAttributeString(AliasStr, alias);
                }
 
                if (!string.IsNullOrEmpty(name)) {
                    Writer.WriteAttributeString(NameStr, name); 
                } 
                //Writer.WriteEndElement();
            } 
            Writer.WriteEndElement();
        }

        private string GetAliasFromName(AssemblyName assemblyName) 
        {
             if (cachedAliases == null) 
            { 
                cachedAliases = new Hashtable();
            } 
            string alias =  (string) cachedAliases[assemblyName.FullName];
            if (string.IsNullOrEmpty(alias))
            {
                alias =  assemblyName.Name; 
                AddAlias(alias, assemblyName);
                AddAssemblyRow(AssemblyStr, alias, assemblyName.FullName); 
            } 
            return alias;
        } 

        /// 
        /// 
        ///     Closes any files or streams locked by the writer. 
        /// 
        // NOTE: Part of IResourceWriter - not protected by class level LinkDemand. 
        public void Close() { 
            Dispose();
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        // NOTE: Part of IDisposable - not protected by class level LinkDemand. 
        public virtual void Dispose() { 
            Dispose(true);
            GC.SuppressFinalize(this); 
        }

        /// 
        protected virtual void Dispose(bool disposing) { 
            if (disposing) {
                if (!hasBeenSaved) { 
                    Generate(); 
                }
                if (xmlTextWriter != null) { 
                    xmlTextWriter.Close();
                    xmlTextWriter = null;
                }
                if (stream != null) { 
                    stream.Close();
                    stream = null; 
                } 
                if (textWriter != null) {
                    textWriter.Close(); 
                    textWriter = null;
                }
            }
        } 

        private string GetTypeName(string typeName) { 
             int indexStart = typeName.IndexOf(","); 
             return ((indexStart == -1) ? typeName : typeName.Substring(0, indexStart));
        } 


        private string GetFullName(string typeName) {
             int indexStart = typeName.IndexOf(","); 
             if(indexStart == -1)
                return null; 
             return typeName.Substring(indexStart + 2); 
        }
 
#if UNUSED
        private string GetSimpleName(string typeName) {
             int indexStart = typeName.IndexOf(",");
             int indexEnd =  typeName.IndexOf(",", indexStart + 1); 
             return typeName.Substring(indexStart + 2, indexEnd - indexStart  - 3);
        } 
 
        static string StripVersionInformation(string typeName) {
            int indexStart = typeName.IndexOf(" Version="); 
            if(indexStart ==-1)
                indexStart = typeName.IndexOf("Version=");
            if(indexStart ==-1)
                indexStart = typeName.IndexOf("version="); 
            int indexEnd = -1;
            string result = typeName; 
            if(indexStart != -1) { 
                // foudn version
                indexEnd = typeName.IndexOf(",", indexStart); 
                if(indexEnd != -1) {
                    result = typeName.Remove(indexStart, indexEnd-indexStart+1);
                }
            } 
            return result;
 
        } 
#endif
 

        static string ToBase64WrappedString(byte[] data) {
            const int lineWrap = 80;
            const string crlf = "\r\n"; 
            const string prefix = "        ";
            string raw = Convert.ToBase64String(data); 
            if (raw.Length > lineWrap) { 
                StringBuilder output = new StringBuilder(raw.Length + (raw.Length / lineWrap) * 3); // word wrap on lineWrap chars, \r\n
                int current = 0; 
                for (; current < raw.Length - lineWrap; current+=lineWrap) {
                    output.Append(crlf);
                    output.Append(prefix);
                    output.Append(raw, current, lineWrap); 
                }
                output.Append(crlf); 
                output.Append(prefix); 
                output.Append(raw, current, raw.Length - current);
                output.Append(crlf); 
                return output.ToString();
            }
            else {
                return raw; 
            }
        } 
 
        private string TypeNameWithAssembly(Type type) {
            // 



 

 
 

 


            string result = MultitargetUtil.GetAssemblyQualifiedName(type, this.typeNameConverter);
            return result; 
        }
 
        ///  
        /// 
        ///     Writes the resources out to the file or stream. 
        /// 
        // NOTE: Part of IResourceWriter - not protected by class level LinkDemand.
        public void Generate() {
            if (hasBeenSaved) 
                throw new InvalidOperationException(SR.GetString(SR.ResXResourceWriterSaved));
 
            hasBeenSaved = true; 
            Debug.WriteLineIf(ResValueProviderSwitch.TraceVerbose, "writing XML");
 
            Writer.WriteEndElement();
            Writer.Flush();

            Debug.WriteLineIf(ResValueProviderSwitch.TraceVerbose, "done"); 
        }
    } 
} 

 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

#if SYSTEM_WEB  // See DevDiv 9030 
namespace System.PrivateResources { 
#else
namespace System.Resources { 
#endif

    using System.Diagnostics;
    using System.Reflection; 
    using System;
    using System.Windows.Forms; 
    using Microsoft.Win32; 
    using System.Drawing;
    using System.IO; 
    using System.Text;
    using System.ComponentModel;
    using System.Collections;
    using System.Resources; 
    using System.Xml;
    using System.Runtime.Serialization; 
    using System.Diagnostics.CodeAnalysis; 
#if SYSTEM_WEB
    using System.Web;   // This is needed to access the SR resource strings 
#endif

    /// 
    ///  
    ///     ResX resource writer. See the text in "ResourceSchema" for more
    ///     information. 
    ///  
    [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.InheritanceDemand, Name="FullTrust")]
    [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name="FullTrust")] 
#if SYSTEM_WEB
    internal class ResXResourceWriter : IResourceWriter {
#else
    public class ResXResourceWriter : IResourceWriter { 
#endif
        internal const string TypeStr = "type"; 
        internal const string NameStr = "name"; 
        internal const string DataStr = "data";
        internal const string MetadataStr = "metadata"; 
        internal const string MimeTypeStr = "mimetype";
        internal const string ValueStr = "value";
        internal const string ResHeaderStr = "resheader";
        internal const string VersionStr = "version"; 
        internal const string ResMimeTypeStr = "resmimetype";
        internal const string ReaderStr = "reader"; 
        internal const string WriterStr = "writer"; 
        internal const string CommentStr = "comment";
        internal const string AssemblyStr ="assembly"; 
        internal const string AliasStr= "alias" ;

        private Hashtable cachedAliases;
 
        private static TraceSwitch ResValueProviderSwitch = new TraceSwitch("ResX", "Debug the resource value provider");
 
        // 

 



 

        internal static readonly string Beta2CompatSerializedObjectMimeType = "text/microsoft-urt/psuedoml-serialized/base64"; 
 
        // These two "compat" mimetypes are here. In Beta 2 and RTM we used the term "URT"
        // internally to refer to parts of the .NET Framework. Since these references 
        // will be in Beta 2 ResX files, and RTM ResX files for customers that had
        // early access to releases, we don't want to break that. We will read
        // and parse these types correctly in version 1.0, but will always
        // write out the new version. So, opening and editing a ResX file in VS will 
        // update it to the new types.
        // 
        internal static readonly string CompatBinSerializedObjectMimeType = "text/microsoft-urt/binary-serialized/base64"; 
        internal static readonly string CompatSoapSerializedObjectMimeType = "text/microsoft-urt/soap-serialized/base64";
 
        /// 
        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public static readonly string BinSerializedObjectMimeType = "application/x-microsoft.net.object.binary.base64"; 
        ///  
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public static readonly string SoapSerializedObjectMimeType = "application/x-microsoft.net.object.soap.base64";
        ///  
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public static readonly string DefaultSerializedObjectMimeType = BinSerializedObjectMimeType; 
        /// 
        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public static readonly string ByteArraySerializedObjectMimeType = "application/x-microsoft.net.object.bytearray.base64"; 
        ///  
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public static readonly string ResMimeType = "text/microsoft-resx";
        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public static readonly string Version = "2.0";
 
        /// 
        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public static readonly string ResourceSchema = @" 
    
    
         
        
             
                 
                    
                         
                            
                            
                            
                             
                            
                             
                             
                        
                     
                    
                      
                        
                         
                      
                     
                     
                        
                             
                                
                                
                            
                             
                            
                             
                             
                        
                     
                    
                        
                            
                                 
                            
                             
                         
                    
                 
            
        
        
        "; 

        IFormatter binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter (); 
        string fileName; 
        Stream stream;
        TextWriter textWriter; 
        XmlTextWriter xmlTextWriter;
        string basePath;

        bool hasBeenSaved; 
        bool initialized;
 
        private Func typeNameConverter; // no public property to be consistent with ResXDataNode class. 

        ///  
        /// 
        ///     Base Path for ResXFileRefs.
        /// 
        public string BasePath { 
            get {
                return basePath; 
            } 
            set {
                basePath = value; 
            }
        }

        ///  
        /// 
        ///     Creates a new ResXResourceWriter that will write to the specified file. 
        ///  
        public ResXResourceWriter(string fileName) {
            this.fileName = fileName; 
        }
        public ResXResourceWriter(string fileName, Func typeNameConverter) {
            this.fileName = fileName;
            this.typeNameConverter = typeNameConverter; 
        }
 
        ///  
        /// 
        ///     Creates a new ResXResourceWriter that will write to the specified stream. 
        /// 
        public ResXResourceWriter(Stream stream) {
            this.stream = stream;
        } 
        public ResXResourceWriter(Stream stream, Func typeNameConverter) {
            this.stream = stream; 
            this.typeNameConverter = typeNameConverter; 
        }
 
        /// 
        /// 
        ///     Creates a new ResXResourceWriter that will write to the specified TextWriter.
        ///  
        public ResXResourceWriter(TextWriter textWriter) {
            this.textWriter = textWriter; 
        } 
        public ResXResourceWriter(TextWriter textWriter, Func typeNameConverter) {
            this.textWriter = textWriter; 
            this.typeNameConverter = typeNameConverter;
        }

        ///  
        ~ResXResourceWriter() {
            Dispose(false); 
        } 

        private void InitializeWriter() { 
            if (xmlTextWriter == null) {
                //

                bool writeHeaderHack = false; 

                if (textWriter != null) { 
                    textWriter.WriteLine(""); 
                    writeHeaderHack = true;
 
                    xmlTextWriter = new XmlTextWriter(textWriter);
                }
                else if (stream != null) {
                    xmlTextWriter = new XmlTextWriter(stream, System.Text.Encoding.UTF8); 
                }
                else { 
                    Debug.Assert(fileName != null, "Nothing to output to"); 
                    xmlTextWriter = new XmlTextWriter(fileName, System.Text.Encoding.UTF8);
                } 
                xmlTextWriter.Formatting = Formatting.Indented;
                xmlTextWriter.Indentation = 2;

                if (!writeHeaderHack) { 
                    xmlTextWriter.WriteStartDocument(); // writes 
                } 
            } 
            else {
                xmlTextWriter.WriteStartDocument(); 
            }

            xmlTextWriter.WriteStartElement("root");
            XmlTextReader reader = new XmlTextReader(new StringReader(ResourceSchema)); 
            reader.WhitespaceHandling = WhitespaceHandling.None;
            xmlTextWriter.WriteNode(reader, true); 
 
            xmlTextWriter.WriteStartElement(ResHeaderStr); {
                xmlTextWriter.WriteAttributeString(NameStr, ResMimeTypeStr); 
                xmlTextWriter.WriteStartElement(ValueStr); {
                    xmlTextWriter.WriteString(ResMimeType);
                }
                xmlTextWriter.WriteEndElement(); 
            }
            xmlTextWriter.WriteEndElement(); 
            xmlTextWriter.WriteStartElement(ResHeaderStr); { 
                xmlTextWriter.WriteAttributeString(NameStr, VersionStr);
                xmlTextWriter.WriteStartElement(ValueStr); { 
                    xmlTextWriter.WriteString(Version);
                }
                xmlTextWriter.WriteEndElement();
            } 
            xmlTextWriter.WriteEndElement();
            xmlTextWriter.WriteStartElement(ResHeaderStr); { 
                xmlTextWriter.WriteAttributeString(NameStr, ReaderStr); 
                xmlTextWriter.WriteStartElement(ValueStr); {
                    xmlTextWriter.WriteString(MultitargetUtil.GetAssemblyQualifiedName(typeof(ResXResourceReader), this.typeNameConverter)); 
                }
                xmlTextWriter.WriteEndElement();
            }
            xmlTextWriter.WriteEndElement(); 
            xmlTextWriter.WriteStartElement(ResHeaderStr); {
                xmlTextWriter.WriteAttributeString(NameStr, WriterStr); 
                xmlTextWriter.WriteStartElement(ValueStr); { 
                    xmlTextWriter.WriteString(MultitargetUtil.GetAssemblyQualifiedName(typeof(ResXResourceWriter), this.typeNameConverter));
                } 
                xmlTextWriter.WriteEndElement();
            }
            xmlTextWriter.WriteEndElement();
 
            initialized = true;
        } 
 
        private XmlWriter Writer {
            get { 
                if (!initialized) {
                    InitializeWriter();
                }
                return xmlTextWriter; 
            }
        } 
 
        /// 
        ///  
        ///    Adds aliases to the resource file...
        /// 
        public virtual void AddAlias(string aliasName, AssemblyName assemblyName) {
           if (assemblyName == null) { 
               throw new ArgumentNullException("assemblyName");
           } 
 
           if (cachedAliases == null) {
               cachedAliases = new Hashtable(); 
           }

           cachedAliases[assemblyName.FullName] = aliasName;
       } 

 
        ///  
        /// 
        ///    Adds the given value to the collection of metadata.  These name/value pairs 
        ///    will be emitted to the  elements in the .resx file.
        /// 
        public void AddMetadata(string name, byte[] value) {
            AddDataRow(MetadataStr, name, value); 
        }
 
        ///  
        /// 
        ///    Adds the given value to the collection of metadata.  These name/value pairs 
        ///    will be emitted to the  elements in the .resx file.
        /// 
        public void AddMetadata(string name, string value) {
            AddDataRow(MetadataStr, name, value); 
        }
 
        ///  
        /// 
        ///    Adds the given value to the collection of metadata.  These name/value pairs 
        ///    will be emitted to the  elements in the .resx file.
        /// 
        public void AddMetadata(string name, object value) {
            AddDataRow(MetadataStr, name, value); 
        }
 
        ///  
        /// 
        ///     Adds a blob resource to the resources. 
        /// 
        // NOTE: Part of IResourceWriter - not protected by class level LinkDemand.
        public void AddResource(string name, byte[] value) {
            AddDataRow(DataStr, name, value); 
        }
 
        ///  
        /// 
        ///     Adds a resource to the resources. If the resource is a string, 
        ///     it will be saved that way, otherwise it will be serialized
        ///     and stored as in binary.
        /// 
        // NOTE: Part of IResourceWriter - not protected by class level LinkDemand. 
        public void AddResource(string name, object value) {
            if (value is ResXDataNode) { 
                AddResource((ResXDataNode)value); 
            }
            else { 
                AddDataRow(DataStr, name, value);
            }
        }
 
        /// 
        ///  
        ///     Adds a string resource to the resources. 
        /// 
        // NOTE: Part of IResourceWriter - not protected by class level LinkDemand. 
        public void AddResource(string name, string value) {
            AddDataRow(DataStr, name, value);
        }
 
         /// 
        ///  
        ///     Adds a string resource to the resources. 
        /// 
        public void AddResource(ResXDataNode node) { 
            // we're modifying the node as we're adding it to the resxwriter
            // this is BAD, so we clone it. adding it to a writer doesnt change it
            // we're messing with a copy
            ResXDataNode nodeClone = node.DeepClone(); 

            ResXFileRef fileRef = nodeClone.FileRef; 
            string modifiedBasePath = BasePath; 

            if (!String.IsNullOrEmpty(modifiedBasePath)) { 
                if (!(modifiedBasePath.EndsWith("\\")))
                {
                    modifiedBasePath += "\\";
                } 
                if (fileRef != null) {
                    fileRef.MakeFilePathRelative(modifiedBasePath); 
                } 
            }
            DataNodeInfo info = nodeClone.GetDataNodeInfo(); 
            AddDataRow(DataStr, info.Name, info.ValueData, info.TypeName, info.MimeType, info.Comment);
        }

        ///  
        ///     Adds a blob resource to the resources.
        ///  
        private void AddDataRow(string elementName, string name, byte[] value) { 
            AddDataRow(elementName, name, ToBase64WrappedString(value), TypeNameWithAssembly(typeof(byte[])), null, null);
        } 

        /// 
        ///     Adds a resource to the resources. If the resource is a string,
        ///     it will be saved that way, otherwise it will be serialized 
        ///     and stored as in binary.
        ///  
        private void AddDataRow(string elementName, string name, object value) { 
            Debug.WriteLineIf(ResValueProviderSwitch.TraceVerbose, "  resx: adding resource " + name);
            if (value is string) { 
                AddDataRow(elementName, name, (string)value);
            }
            else if (value is byte[]) {
                AddDataRow(elementName, name, (byte[])value); 
            }
            else if(value is ResXFileRef) { 
                ResXFileRef fileRef = (ResXFileRef)value; 
                ResXDataNode node = new ResXDataNode(name, fileRef, this.typeNameConverter);
                if (fileRef != null) { 
                    fileRef.MakeFilePathRelative(BasePath);
                }
                DataNodeInfo info = node.GetDataNodeInfo();
                AddDataRow(elementName, info.Name, info.ValueData, info.TypeName, info.MimeType, info.Comment); 
            } else {
                ResXDataNode node = new ResXDataNode(name, value, this.typeNameConverter); 
                DataNodeInfo info = node.GetDataNodeInfo(); 
                AddDataRow(elementName, info.Name, info.ValueData, info.TypeName, info.MimeType, info.Comment);
            } 
        }

        /// 
        ///     Adds a string resource to the resources. 
        /// 
        private void AddDataRow(string elementName, string name, string value) { 
            if(value == null) { 
                // if it's a null string, set it here as a resxnullref
                AddDataRow(elementName, name, value, MultitargetUtil.GetAssemblyQualifiedName(typeof(ResXNullRef), this.typeNameConverter), null, null); 
            } else {
                AddDataRow(elementName, name, value, null, null, null);
            }
        } 

        ///  
        ///     Adds a new row to the Resources table. This helper is used because 
        ///     we want to always late bind to the columns for greater flexibility.
        ///  
        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        private void AddDataRow(string elementName, string name, string value, string type, string mimeType, string comment) {
            if (hasBeenSaved)
                throw new InvalidOperationException(SR.GetString(SR.ResXResourceWriterSaved)); 

            string alias = null; 
            if (!string.IsNullOrEmpty(type) && elementName == DataStr) 
            {
                string assemblyName = GetFullName(type); 
                if(string.IsNullOrEmpty(assemblyName)) {
                    try {
                        Type typeObject = Type.GetType(type);
                        if(typeObject == typeof(string)) { 
                            type = null;
                        } else if(typeObject != null) { 
                            assemblyName = GetFullName(MultitargetUtil.GetAssemblyQualifiedName(typeObject, this.typeNameConverter)); 
                            alias = GetAliasFromName(new AssemblyName(assemblyName));
                        } 
                    } catch {
                    }
                } else {
                    alias = GetAliasFromName(new AssemblyName(GetFullName(type))); 
                }
                //AddAssemblyRow(AssemblyStr, alias, GetFullName(type)); 
            } 

            Writer.WriteStartElement(elementName); { 
                Writer.WriteAttributeString(NameStr, name);

                if (!string.IsNullOrEmpty(alias) && !string.IsNullOrEmpty(type) && elementName == DataStr) {
                     // CHANGE: we still output version information. This might have 
                    // to change in 3.2
                    string typeName = GetTypeName(type); 
                    string typeValue = typeName + ", " + alias; 
                    Writer.WriteAttributeString(TypeStr, typeValue);
                } 
                else {
                     if (type != null)
                     {
                        Writer.WriteAttributeString(TypeStr, type); 
                     }
                } 
 
                if (mimeType != null) {
                    Writer.WriteAttributeString(MimeTypeStr, mimeType); 
                }

                if((type == null && mimeType == null) || (type != null && type.StartsWith("System.Char", StringComparison.Ordinal))) {
                    Writer.WriteAttributeString("xml", "space", null, "preserve"); 
                }
 
                Writer.WriteStartElement(ValueStr); { 
                    if(!string.IsNullOrEmpty(value)) {
                        Writer.WriteString(value); 
                    }
                }
                Writer.WriteEndElement();
                if(!string.IsNullOrEmpty(comment)) { 
                    Writer.WriteStartElement(CommentStr); {
                        Writer.WriteString(comment); 
                    } 
                    Writer.WriteEndElement();
                } 
            }
            Writer.WriteEndElement();
        }
 

        private void AddAssemblyRow(string elementName, string alias, string name) 
        { 

            Writer.WriteStartElement(elementName); { 
                if (!string.IsNullOrEmpty(alias)) {
                      Writer.WriteAttributeString(AliasStr, alias);
                }
 
                if (!string.IsNullOrEmpty(name)) {
                    Writer.WriteAttributeString(NameStr, name); 
                } 
                //Writer.WriteEndElement();
            } 
            Writer.WriteEndElement();
        }

        private string GetAliasFromName(AssemblyName assemblyName) 
        {
             if (cachedAliases == null) 
            { 
                cachedAliases = new Hashtable();
            } 
            string alias =  (string) cachedAliases[assemblyName.FullName];
            if (string.IsNullOrEmpty(alias))
            {
                alias =  assemblyName.Name; 
                AddAlias(alias, assemblyName);
                AddAssemblyRow(AssemblyStr, alias, assemblyName.FullName); 
            } 
            return alias;
        } 

        /// 
        /// 
        ///     Closes any files or streams locked by the writer. 
        /// 
        // NOTE: Part of IResourceWriter - not protected by class level LinkDemand. 
        public void Close() { 
            Dispose();
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        // NOTE: Part of IDisposable - not protected by class level LinkDemand. 
        public virtual void Dispose() { 
            Dispose(true);
            GC.SuppressFinalize(this); 
        }

        /// 
        protected virtual void Dispose(bool disposing) { 
            if (disposing) {
                if (!hasBeenSaved) { 
                    Generate(); 
                }
                if (xmlTextWriter != null) { 
                    xmlTextWriter.Close();
                    xmlTextWriter = null;
                }
                if (stream != null) { 
                    stream.Close();
                    stream = null; 
                } 
                if (textWriter != null) {
                    textWriter.Close(); 
                    textWriter = null;
                }
            }
        } 

        private string GetTypeName(string typeName) { 
             int indexStart = typeName.IndexOf(","); 
             return ((indexStart == -1) ? typeName : typeName.Substring(0, indexStart));
        } 


        private string GetFullName(string typeName) {
             int indexStart = typeName.IndexOf(","); 
             if(indexStart == -1)
                return null; 
             return typeName.Substring(indexStart + 2); 
        }
 
#if UNUSED
        private string GetSimpleName(string typeName) {
             int indexStart = typeName.IndexOf(",");
             int indexEnd =  typeName.IndexOf(",", indexStart + 1); 
             return typeName.Substring(indexStart + 2, indexEnd - indexStart  - 3);
        } 
 
        static string StripVersionInformation(string typeName) {
            int indexStart = typeName.IndexOf(" Version="); 
            if(indexStart ==-1)
                indexStart = typeName.IndexOf("Version=");
            if(indexStart ==-1)
                indexStart = typeName.IndexOf("version="); 
            int indexEnd = -1;
            string result = typeName; 
            if(indexStart != -1) { 
                // foudn version
                indexEnd = typeName.IndexOf(",", indexStart); 
                if(indexEnd != -1) {
                    result = typeName.Remove(indexStart, indexEnd-indexStart+1);
                }
            } 
            return result;
 
        } 
#endif
 

        static string ToBase64WrappedString(byte[] data) {
            const int lineWrap = 80;
            const string crlf = "\r\n"; 
            const string prefix = "        ";
            string raw = Convert.ToBase64String(data); 
            if (raw.Length > lineWrap) { 
                StringBuilder output = new StringBuilder(raw.Length + (raw.Length / lineWrap) * 3); // word wrap on lineWrap chars, \r\n
                int current = 0; 
                for (; current < raw.Length - lineWrap; current+=lineWrap) {
                    output.Append(crlf);
                    output.Append(prefix);
                    output.Append(raw, current, lineWrap); 
                }
                output.Append(crlf); 
                output.Append(prefix); 
                output.Append(raw, current, raw.Length - current);
                output.Append(crlf); 
                return output.ToString();
            }
            else {
                return raw; 
            }
        } 
 
        private string TypeNameWithAssembly(Type type) {
            // 



 

 
 

 


            string result = MultitargetUtil.GetAssemblyQualifiedName(type, this.typeNameConverter);
            return result; 
        }
 
        ///  
        /// 
        ///     Writes the resources out to the file or stream. 
        /// 
        // NOTE: Part of IResourceWriter - not protected by class level LinkDemand.
        public void Generate() {
            if (hasBeenSaved) 
                throw new InvalidOperationException(SR.GetString(SR.ResXResourceWriterSaved));
 
            hasBeenSaved = true; 
            Debug.WriteLineIf(ResValueProviderSwitch.TraceVerbose, "writing XML");
 
            Writer.WriteEndElement();
            Writer.Flush();

            Debug.WriteLineIf(ResValueProviderSwitch.TraceVerbose, "done"); 
        }
    } 
} 

 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK