ResXResourceWriter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / Resources / ResXResourceWriter.cs / 1 / 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;
 
 

        ///  
        /// 
        ///     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; 
        }

        /// 
        ///  
        ///     Creates a new ResXResourceWriter that will write to the specified stream.
        ///  
        public ResXResourceWriter(Stream stream) { 
            this.stream = stream;
        } 

        /// 
        /// 
        ///     Creates a new ResXResourceWriter that will write to the specified TextWriter. 
        /// 
        public ResXResourceWriter(TextWriter textWriter) { 
            this.textWriter = textWriter; 
        }
 
        /// 
        ~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(typeof(ResXResourceReader).AssemblyQualifiedName); 
                } 
                xmlTextWriter.WriteEndElement();
            } 
            xmlTextWriter.WriteEndElement();
            xmlTextWriter.WriteStartElement(ResHeaderStr); {
                xmlTextWriter.WriteAttributeString(NameStr, WriterStr);
                xmlTextWriter.WriteStartElement(ValueStr); { 
                    xmlTextWriter.WriteString(typeof(ResXResourceWriter).AssemblyQualifiedName);
                } 
                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);
                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);
                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, typeof(ResXNullRef).AssemblyQualifiedName, 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(typeObject.AssemblyQualifiedName); 
                            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 = type.AssemblyQualifiedName; 
            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.
                        

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