ResXDataNode.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / Resources / ResXDataNode.cs / 1305376 / ResXDataNode.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.Diagnostics.CodeAnalysis; 
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary; 
    using System; 
    using System.Windows.Forms;
    using System.Reflection; 
    using Microsoft.Win32;
    using System.Drawing;
    using System.IO;
    using System.Text; 
    using System.ComponentModel;
    using System.Collections; 
    using System.Runtime.CompilerServices; 
    using System.Resources;
    using System.Xml; 
    using System.ComponentModel.Design;
    using System.Globalization;
    using System.Security.Permissions;
    using System.Runtime.Versioning; 
#if SYSTEM_WEB
    using System.Web;   // This is needed to access the SR resource strings 
#endif 

 
    /// 
    /// 
    ///
    ///  
    [Serializable]
    [PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name="FullTrust")] 
#if SYSTEM_WEB 
    internal sealed class ResXDataNode : ISerializable {
#else 
    public sealed class ResXDataNode : ISerializable {
#endif

        private static readonly char[] SpecialChars = new char[]{' ', '\r', '\n'}; 

        private DataNodeInfo        nodeInfo; 
 
        private string name;
        private string comment; 
#if UNUSED
        private string mimeType;
        private string valueData;
#endif 

        private string typeName; // is only used when we create a resxdatanode manually with an object and contains the FQN 
 
        private string fileRefFullPath;
        private string fileRefType; 
        private string fileRefTextEncoding;

        private object              value;
        private ResXFileRef         fileRef; 

        private IFormatter binaryFormatter = null; 
 
        // this is going to be used to check if a ResXDataNode is of type ResXFileRef
        private static ITypeResolutionService internalTypeResolver = new AssemblyNamesTypeResolutionService(new AssemblyName[] { new AssemblyName("System.Windows.Forms") }); 

        // call back function to get type name for multitargeting.
        // No public property to force using constructors for the following reasons:
        // 1. one of the constructors needs this field (if used) to initialize the object, make it consistent with the other ctrs to avoid errors. 
        // 2. once the object is constructed the delegate should not be changed to avoid getting inconsistent results.
        private Func typeNameConverter; 
 
        // constructors
 
        private ResXDataNode() {
        }

        //  
        // this is a deep clone
        // 
        internal ResXDataNode DeepClone() { 
            ResXDataNode result = new ResXDataNode();
            result.nodeInfo = (this.nodeInfo != null) ? this.nodeInfo.Clone() : null; // nodeinfo is just made up of immutable objects, we don't need to clone it 
            result.name = this.name;
            result.comment = this.comment;
#if UNUSED
            result.mimeType = this.mimeType; 
            result.valueData = this.valueData;
#endif 
            result.typeName = this.typeName; 
            result.fileRefFullPath = this.fileRefFullPath;
            result.fileRefType = this.fileRefType; 
            result.fileRefTextEncoding = this.fileRefTextEncoding;
            result.value = this.value; // we don't clone the value, because we don't know how
            result.fileRef = (this.fileRef != null) ? this.fileRef.Clone() : null;
            result.typeNameConverter = this.typeNameConverter; 
            return result;
        } 
 
        /// 
        ///  
        ///
        /// 
        public ResXDataNode(string name, object value) : this(name, value, null) {
        } 

        [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] 
        [ 
            SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters") // "name" is the name of the param passed in.
            // So we don't have to localize it. 
        ]
        public ResXDataNode(string name, object value, Func typeNameConverter) {
            if(name == null) {
                throw (new ArgumentNullException("name")); 
            }
            if(name.Length == 0) { 
                throw (new ArgumentException("name")); 
            }
 
            this.typeNameConverter = typeNameConverter;

            Type valueType = (value == null) ? typeof(object) : value.GetType();
            if (value != null && !valueType.IsSerializable) { 
                throw new InvalidOperationException(SR.GetString(SR.NotSerializableType, name, valueType.FullName));
            } else if (value!= null) { 
                this.typeName = MultitargetUtil.GetAssemblyQualifiedName(valueType, this.typeNameConverter); 
            }
 
            this.name = name;
            this.value = value;
        }
 
        /// 
        ///  
        /// 
        /// 
        public ResXDataNode(string name, ResXFileRef fileRef) : this(name, fileRef, null) { 
        }

        [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")]
        [ 
            SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters") // "name" is the name of the param passed in.
                                                                                                        // So we don't have to localize it. 
        ] 
        public ResXDataNode(string name, ResXFileRef fileRef, Func typeNameConverter) {
            if(name == null) { 
                throw (new ArgumentNullException("name"));
            }
            if(fileRef == null) {
                throw (new ArgumentNullException("fileRef")); 
            }
            if(name.Length == 0) { 
                throw (new ArgumentException("name")); 
            }
            this.name = name; 
            this.fileRef = fileRef;
            this.typeNameConverter = typeNameConverter;
        }
 
        internal ResXDataNode(DataNodeInfo nodeInfo, string basePath) {
            this.nodeInfo = nodeInfo; 
            InitializeDataNode(basePath); 
        }
 
        private void InitializeDataNode(string basePath) {

            // we can only use our internal type resolver here
            // because we only want to check if this is a ResXFileRef node 
            // and we can't be sure that we have a typeResolutionService that can
            // recognize this. It's not very clean but this should work. 
            Type nodeType = null; 
            if(!string.IsNullOrEmpty(nodeInfo.TypeName)) // can be null if we have a string (default for string is TypeName == null)
                nodeType = internalTypeResolver.GetType(nodeInfo.TypeName, false, true); 
            if(nodeType != null && nodeType.Equals(typeof(ResXFileRef))) {
                // we have a fileref, split the value data and populate the fields
                string[] fileRefDetails = ResXFileRef.Converter.ParseResxFileRefString(nodeInfo.ValueData);
                if(fileRefDetails != null && fileRefDetails.Length > 1) { 
                    if(!Path.IsPathRooted(fileRefDetails[0]) && basePath != null) {
                        fileRefFullPath = Path.Combine(basePath, fileRefDetails[0]); 
                    } else { 
                        fileRefFullPath = fileRefDetails[0];
                    } 
                    fileRefType = fileRefDetails[1];
                    if(fileRefDetails.Length > 2) {
                        fileRefTextEncoding = fileRefDetails[2];
                    } 
                }
            } 
        } 

 
        /// 
        /// 
        ///
        ///  
        public string Comment {
            get { 
                string result = comment; 
                if(result == null && nodeInfo != null) {
                    result = nodeInfo.Comment; 
                }
                return (result == null ? "" : result);
            }
            set { 
                comment= value;
            } 
        } 

        ///  
        /// 
        ///
        /// 
        public string Name { 
            get {
                string result = name; 
                if(result == null && nodeInfo != null) { 
                    result = nodeInfo.Name;
                } 
                return result;
            }
            [
                SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters") // "Name" is the name of the property. 
                                                                                                            // So we don't have to localize it.
            ] 
            set { 
                if(value == null) {
                    throw (new ArgumentNullException("Name")); 
                }
                if(value.Length == 0) {
                    throw (new ArgumentException("Name"));
                } 
                name = value;
            } 
        } 

#if UNUSED 
        private string MimeType {
            get {
                string result = mimeType;
                if(result == null && nodeInfo != null) { 
                    result = nodeInfo.MimeType;
                } 
                return result; 
            }
        } 

        private string ValueData {
            get {
                string result = valueData; 
                if(result == null && nodeInfo != null) {
                    result = nodeInfo.ValueData; 
                } 
                return result;
            } 
        }
#endif

        ///  
        /// 
        /// 
        ///  
        public ResXFileRef FileRef {
            get { 
                if(FileRefFullPath==null) {
                    return null;
                }
                if(fileRef == null) { 
                    if(String.IsNullOrEmpty(fileRefTextEncoding))
                    { 
                        fileRef = new ResXFileRef(FileRefFullPath, FileRefType); 
                    } else {
                        fileRef = new ResXFileRef(FileRefFullPath, FileRefType, Encoding.GetEncoding(FileRefTextEncoding)); 
                    }
                }
                return fileRef;
            } 
        }
 
 
        private string FileRefFullPath {
            get { 
                string result = (fileRef==null ? null : fileRef.FileName);
                if(result == null) {
                    result = fileRefFullPath;
                } 
                return result;
            } 
        } 

        private string FileRefType { 
            get {
                string result = (fileRef==null ? null : fileRef.TypeName);
                if(result == null) {
                    result = fileRefType; 
                }
                return result; 
            } 
        }
 
        private string FileRefTextEncoding {
            get {
                string result = (fileRef==null ? null : (fileRef.TextFileEncoding == null ? null : fileRef.TextFileEncoding.BodyName));
                if(result == null) { 
                    result = fileRefTextEncoding;
                } 
 
                return result;
            } 
        }


#if !SYSTEM_WEB     // System.Web does not link with the Soap assembly 
        /// 
        ///     As a performance optimization, we isolate the soap class here in a separate 
        ///     function.  We don't care about the binary formatter because it lives in 
        ///     mscorlib, which is already loaded.  The soap formatter lives in a separate
        ///     assembly, however, so there is value in preventing it from needlessly 
        ///     being loaded.
        /// 
        [MethodImplAttribute(MethodImplOptions.NoInlining)]
        private IFormatter CreateSoapFormatter() { 
            return new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
        } 
#endif 

 
        private 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 void FillDataNodeInfoFromObject(DataNodeInfo nodeInfo, object value) { 
            CultureInfo ci = value as CultureInfo;
            if( ci != null) { // special-case CultureInfo, cannot use CultureInfoConverter for serialization (see DevDiv#578701). 
                nodeInfo.ValueData = ci.Name;
                nodeInfo.TypeName = MultitargetUtil.GetAssemblyQualifiedName(typeof(CultureInfo), this.typeNameConverter);
            }
            else if (value is string) { 
                nodeInfo.ValueData = (string)value;
                if(value == null) { 
                    nodeInfo.TypeName = MultitargetUtil.GetAssemblyQualifiedName(typeof(ResXNullRef), this.typeNameConverter); 
                }
            } 
            else if (value is byte[]) {
                nodeInfo.ValueData = ToBase64WrappedString((byte[])value);
                nodeInfo.TypeName = MultitargetUtil.GetAssemblyQualifiedName(typeof(byte[]), this.typeNameConverter);
            } 
            else {
                Type valueType = (value == null) ? typeof(object) : value.GetType(); 
                if (value != null && !valueType.IsSerializable) { 
                    throw new InvalidOperationException(SR.GetString(SR.NotSerializableType, name, valueType.FullName));
                } 
                TypeConverter tc = TypeDescriptor.GetConverter(valueType);
                bool toString = tc.CanConvertTo(typeof(string));
                bool fromString = tc.CanConvertFrom(typeof(string));
                try { 
                    if (toString && fromString) {
                        nodeInfo.ValueData = tc.ConvertToInvariantString(value); 
                        nodeInfo.TypeName = MultitargetUtil.GetAssemblyQualifiedName(valueType, this.typeNameConverter); 
                        return;
                    } 
                }
                catch (Exception ex) {
                    // Some custom type converters will throw in ConvertTo(string)
                    // to indicate that this object should be serialized through ISeriazable 
                    // instead of as a string. This is semi-wrong, but something we will have to
                    // live with to allow user created Cursors to be serializable. 
                    if (ClientUtils.IsSecurityOrCriticalException(ex)) { 
                        throw;
                    } 
                }

                bool toByteArray = tc.CanConvertTo(typeof(byte[]));
                bool fromByteArray = tc.CanConvertFrom(typeof(byte[])); 
                if (toByteArray && fromByteArray) {
                    byte[] data = (byte[])tc.ConvertTo(value, typeof(byte[])); 
                    string text = ToBase64WrappedString(data); 
                    nodeInfo.ValueData = text;
                    nodeInfo.MimeType = ResXResourceWriter.ByteArraySerializedObjectMimeType; 
                    nodeInfo.TypeName = MultitargetUtil.GetAssemblyQualifiedName(valueType, this.typeNameConverter);
                    return;
                }
 
                if (value == null) {
                    nodeInfo.ValueData = string.Empty; 
                    nodeInfo.TypeName = MultitargetUtil.GetAssemblyQualifiedName(typeof(ResXNullRef), this.typeNameConverter); 
                }
                else { 
                    if (binaryFormatter == null) {
                        binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                    }
 
                    MemoryStream ms = new MemoryStream();
                    if (binaryFormatter == null) { 
                        binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 
                    }
                    IFormatter formatter = binaryFormatter; 
                    formatter.Serialize(ms, value);
                    string text = ToBase64WrappedString(ms.ToArray());
                    nodeInfo.ValueData = text;
                    nodeInfo.MimeType = ResXResourceWriter.DefaultSerializedObjectMimeType; 
                }
            } 
 
        }
 

        private object GenerateObjectFromDataNodeInfo(DataNodeInfo dataNodeInfo, ITypeResolutionService typeResolver) {
            object result = null;
            string mimeTypeName = dataNodeInfo.MimeType; 
            // default behavior: if we dont have a type name, it's a string
            string typeName = (dataNodeInfo.TypeName == null || dataNodeInfo.TypeName.Length==0 ? MultitargetUtil.GetAssemblyQualifiedName(typeof(string), this.typeNameConverter) : dataNodeInfo.TypeName); 
 
            if (mimeTypeName != null && mimeTypeName.Length > 0) {
                if (String.Equals(mimeTypeName, ResXResourceWriter.BinSerializedObjectMimeType) 
                    || String.Equals(mimeTypeName, ResXResourceWriter.Beta2CompatSerializedObjectMimeType)
                    || String.Equals(mimeTypeName, ResXResourceWriter.CompatBinSerializedObjectMimeType)) {
                    string text = dataNodeInfo.ValueData;
                    byte[] serializedData; 
                    serializedData = FromBase64WrappedString(text);
 
                    if (binaryFormatter == null) { 
                        binaryFormatter = new BinaryFormatter();
                        binaryFormatter.Binder = new ResXSerializationBinder(typeResolver); 
                    }
                    IFormatter formatter = binaryFormatter;
                    if (serializedData != null && serializedData.Length > 0) {
                        result = formatter.Deserialize(new MemoryStream(serializedData)); 
                        if (result is ResXNullRef) {
                            result = null; 
                        } 
                    }
                } 
#if !SYSTEM_WEB // System.Web does not link with the Soap assembly
                else if (String.Equals(mimeTypeName, ResXResourceWriter.SoapSerializedObjectMimeType)
                         || String.Equals(mimeTypeName, ResXResourceWriter.CompatSoapSerializedObjectMimeType)) {
                    string text = dataNodeInfo.ValueData; 
                    byte[] serializedData;
                    serializedData = FromBase64WrappedString(text); 
 
                    if (serializedData != null && serializedData.Length > 0) {
 
                        // Performance : don't inline a new SoapFormatter here.  That will always bring in
                        //               the soap assembly, which we don't want.  Throw this in another
                        //               function so the class doesn't have to get loaded.
                        // 
                        IFormatter formatter = CreateSoapFormatter();
                        result = formatter.Deserialize(new MemoryStream(serializedData)); 
                        if (result is ResXNullRef) { 
                            result = null;
                        } 
                    }
                }
#endif
                else if (String.Equals(mimeTypeName, ResXResourceWriter.ByteArraySerializedObjectMimeType)) { 
                    if (typeName != null && typeName.Length > 0) {
                        Type type = ResolveType(typeName, typeResolver); 
                        if (type != null) { 
                            TypeConverter tc = TypeDescriptor.GetConverter(type);
                            if (tc.CanConvertFrom(typeof(byte[]))) { 
                                string text = dataNodeInfo.ValueData;
                                byte[] serializedData;
                                serializedData = FromBase64WrappedString(text);
 
                                if (serializedData != null) {
                                    result = tc.ConvertFrom(serializedData); 
                                } 
                            }
                        } 
                        else {
                            string newMessage = SR.GetString(SR.TypeLoadException, typeName, dataNodeInfo.ReaderPosition.Y, dataNodeInfo.ReaderPosition.X);
                            XmlException xml = new XmlException(newMessage, null, dataNodeInfo.ReaderPosition.Y, dataNodeInfo.ReaderPosition.X);
                            TypeLoadException newTle = new TypeLoadException(newMessage, xml); 

                            throw newTle; 
                        } 
                    }
                } 
            }
            else if (typeName != null && typeName.Length > 0) {
                Type type = ResolveType(typeName, typeResolver);
                if (type != null) { 
                    if (type == typeof(ResXNullRef)) {
                        result = null; 
                    } 
                    else if (typeName.IndexOf("System.Byte[]") != -1 && typeName.IndexOf("mscorlib") != -1) {
                        // Handle byte[]'s, which are stored as base-64 encoded strings. 
                        // We can't hard-code byte[] type name due to version number
                        // updates & potential whitespace issues with ResX files.
                        result = FromBase64WrappedString(dataNodeInfo.ValueData);
                    } 
                    else {
                        TypeConverter tc = TypeDescriptor.GetConverter(type); 
                        if (tc.CanConvertFrom(typeof(string))) { 
                            string text = dataNodeInfo.ValueData;
                            try { 
                            result = tc.ConvertFromInvariantString(text);
                            } catch (NotSupportedException nse) {
                                string newMessage = SR.GetString(SR.NotSupported, typeName, dataNodeInfo.ReaderPosition.Y, dataNodeInfo.ReaderPosition.X, nse.Message);
                                XmlException xml = new XmlException(newMessage, nse, dataNodeInfo.ReaderPosition.Y, dataNodeInfo.ReaderPosition.X); 
                                NotSupportedException newNse = new NotSupportedException(newMessage, xml);
                                throw newNse; 
                            } 
                        }
                        else { 
                            Debug.WriteLine("Converter for " + type.FullName + " doesn't support string conversion");
                        }
                    }
                } 
                else {
                    string newMessage = SR.GetString(SR.TypeLoadException, typeName, dataNodeInfo.ReaderPosition.Y, dataNodeInfo.ReaderPosition.X); 
                    XmlException xml = new XmlException(newMessage, null, dataNodeInfo.ReaderPosition.Y, dataNodeInfo.ReaderPosition.X); 
                    TypeLoadException newTle = new TypeLoadException(newMessage, xml);
 
                    throw newTle;
                }
            }
            else { 
                // if mimeTypeName and typeName are not filled in, the value must be a string
                Debug.Assert(value is string, "Resource entries with no Type or MimeType must be encoded as strings"); 
            } 
            return result;
        } 

        internal DataNodeInfo GetDataNodeInfo() {
            bool shouldSerialize = true;
            if(nodeInfo != null) { 
                shouldSerialize = false;
            } else { 
                nodeInfo = new DataNodeInfo(); 
            }
            nodeInfo.Name = Name; 
            nodeInfo.Comment = Comment;

            // We always serialize if this node represents a FileRef. This is because FileRef is a public property,
            // so someone could have modified it. 
            if(shouldSerialize || FileRefFullPath != null) {
                // if we dont have a datanodeinfo it could be either 
                // a direct object OR a fileref 
                if(FileRefFullPath != null) {
                    nodeInfo.ValueData = FileRef.ToString(); 
                    nodeInfo.MimeType = null;
                    nodeInfo.TypeName = MultitargetUtil.GetAssemblyQualifiedName(typeof(ResXFileRef), this.typeNameConverter);
                } else {
                    // serialize to string inside the nodeInfo 
                    FillDataNodeInfoFromObject(nodeInfo, value);
                } 
 
            }
            return nodeInfo; 
        }

        /// 
        ///  
        ///    Might return the position in the resx file of the current node, if known
        ///    otherwise, will return Point(0,0) since point is a struct 
        ///  
        public Point GetNodePosition() {
            if(nodeInfo == null) { 
                return new Point();
            } else {
                return nodeInfo.ReaderPosition;
            } 
        }
 
        ///  
        /// 
        ///    Get the FQ type name for this datanode. 
        ///    We return typeof(object) for ResXNullRef
        /// 
        public string GetValueTypeName(ITypeResolutionService typeResolver) {
            // the type name here is always a FQN 
            if(typeName != null && typeName.Length >0) {
                if (typeName.Equals(MultitargetUtil.GetAssemblyQualifiedName(typeof(ResXNullRef), this.typeNameConverter))) { 
                    return MultitargetUtil.GetAssemblyQualifiedName(typeof(object), this.typeNameConverter); 
                } else {
                    return typeName; 
                }
            }
            string result = FileRefType;
            Type objectType = null; 
            // do we have a fileref?
            if(result != null) { 
                // try to resolve this type 
                objectType = ResolveType(FileRefType, typeResolver);
            } else if(nodeInfo != null) { 

                // we dont have a fileref, try to resolve the type of the datanode
                result = nodeInfo.TypeName;
                // if typename is null, the default is just a string 
                if(result == null || result.Length==0) {
                    // we still dont know... do we have a mimetype? if yes, our only option is to 
                    // deserialize to know what we're dealing with... very inefficient... 
                    if(nodeInfo.MimeType != null && nodeInfo.MimeType.Length > 0) {
                        object insideObject = null; 

                        try {
                            insideObject = GenerateObjectFromDataNodeInfo(nodeInfo, typeResolver);
                        } catch (Exception ex) { // it'd be better to catch SerializationException but the underlying type resolver 
                                                // can throw things like FileNotFoundException which is kinda confusing, so I am catching all here..
                            if(ClientUtils.IsCriticalException(ex)) { 
                                throw; 
                            }
                            // something went wrong, type is not specified at all or stream is corrupted 
                            // return system.object
                            result = MultitargetUtil.GetAssemblyQualifiedName(typeof(object), this.typeNameConverter);
                        }
 
                        if(insideObject != null) {
                            result = MultitargetUtil.GetAssemblyQualifiedName(insideObject.GetType(), this.typeNameConverter); 
                        } 
                    } else {
                        // no typename, no mimetype, we have a string... 
                        result = MultitargetUtil.GetAssemblyQualifiedName(typeof(string), this.typeNameConverter);
                    }
                } else {
                    objectType = ResolveType(nodeInfo.TypeName, typeResolver); 
                }
            } 
            if(objectType != null) { 
                if(objectType == typeof(ResXNullRef)) {
                    result = MultitargetUtil.GetAssemblyQualifiedName(typeof(object), this.typeNameConverter); 
                } else {
                    result = MultitargetUtil.GetAssemblyQualifiedName(objectType, this.typeNameConverter);
                }
            } 
            return result;
        } 
 
        /// 
        ///  
        ///    Get the FQ type name for this datanode
        /// 
        public string GetValueTypeName(AssemblyName[] names) {
            return GetValueTypeName(new AssemblyNamesTypeResolutionService(names)); 
        }
 
        ///  
        /// 
        ///    Get the value contained in this datanode 
        /// 
        public object GetValue(ITypeResolutionService typeResolver) {

            if(value != null) { 
                return value;
            } 
 
            object result = null;
            if(FileRefFullPath != null) { 
                Type objectType = ResolveType(FileRefType , typeResolver);
                if(objectType != null) {
                    // we have the FQN for this type
                    if(FileRefTextEncoding != null) { 
                        fileRef = new ResXFileRef(FileRefFullPath, FileRefType, Encoding.GetEncoding(FileRefTextEncoding));
                    } else { 
                        fileRef = new ResXFileRef(FileRefFullPath, FileRefType); 
                    }
                    TypeConverter tc = TypeDescriptor.GetConverter(typeof(ResXFileRef)); 
                    result = tc.ConvertFrom(fileRef.ToString());
                } else {
                    string newMessage = SR.GetString(SR.TypeLoadExceptionShort, FileRefType);
                    TypeLoadException newTle = new TypeLoadException(newMessage); 
                    throw (newTle);
                } 
            } else if(result == null && nodeInfo.ValueData!= null) { 
                // it's embedded, we deserialize it
                result = GenerateObjectFromDataNodeInfo(nodeInfo, typeResolver); 
            } else {
                // schema is wrong and say minOccur for Value is 0,
                // but it's too late to change it...
                // we need to return null here vswhidbey 180605 
                return null;
            } 
            return result; 
        }
 
        /// 
        /// 
        ///    Get the value contained in this datanode
        ///  
        public object GetValue(AssemblyName[] names) {
            return GetValue(new AssemblyNamesTypeResolutionService(names)); 
        } 

        private static byte[] FromBase64WrappedString(string text) { 

            if (text.IndexOfAny(SpecialChars) != -1) {
                StringBuilder sb = new StringBuilder(text.Length);
                for (int i=0; i= 2) { 
                        string partialName = typeParts[0].Trim();
                        string assemblyName = typeParts[1].Trim(); 
                        partialName = partialName + ", " + assemblyName; 
                        t = typeResolver.GetType(partialName, false);
                    } 
                }
            }

            if (t == null) { 
                t = Type.GetType(typeName, false);
            } 
 
            return t;
        } 


        /// 
        ///  
        ///    Get the value contained in this datanode
        ///  
        // NOTE: No LinkDemand for SerializationFormatter necessary here, since this class already 
        // has a FullTrust LinkDemand.
        void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) { 
            DataNodeInfo nodeInfo = GetDataNodeInfo();
            si.AddValue("Name", nodeInfo.Name, typeof(string));
            si.AddValue("Comment", nodeInfo.Comment, typeof(string));
            si.AddValue("TypeName", nodeInfo.TypeName, typeof(string)); 
            si.AddValue("MimeType", nodeInfo.MimeType, typeof(string));
            si.AddValue("ValueData", nodeInfo.ValueData, typeof(string)); 
        } 

        private ResXDataNode(SerializationInfo info, StreamingContext context) { 
            DataNodeInfo nodeInfo = new DataNodeInfo();
            nodeInfo.Name = (string)info.GetValue("Name", typeof(string));
            nodeInfo.Comment = (string)info.GetValue("Comment", typeof(string));
            nodeInfo.TypeName = (string)info.GetValue("TypeName", typeof(string)); 
            nodeInfo.MimeType = (string)info.GetValue("MimeType", typeof(string));
            nodeInfo.ValueData = (string)info.GetValue("ValueData", typeof(string)); 
            this.nodeInfo = nodeInfo; 
            InitializeDataNode(null);
        } 
    }

    internal class DataNodeInfo {
        internal string Name; 
        internal string Comment;
        internal string TypeName; 
        internal string MimeType; 
        internal string ValueData;
        internal Point ReaderPosition; //only used to track position in the reader 

        internal DataNodeInfo Clone() {
            DataNodeInfo result  = new DataNodeInfo();
            result.Name = this.Name; 
            result.Comment = this.Comment;
            result.TypeName = this.TypeName; 
            result.MimeType = this.MimeType; 
            result.ValueData = this.ValueData;
            result.ReaderPosition = new Point(this.ReaderPosition.X, this.ReaderPosition.Y); 
            return result;
        }
    }
 
    // This class implements a partial type resolver for the BinaryFormatter.
    // This is needed to be able to read binary serialized content from older 
    // NDP types and map them to newer versions. 
    //
    internal class ResXSerializationBinder : SerializationBinder { 
        private ITypeResolutionService typeResolver;

        internal ResXSerializationBinder(ITypeResolutionService typeResolver) {
            this.typeResolver = typeResolver; 
        }
 
        public override Type BindToType(string assemblyName, string typeName) { 
            if (typeResolver == null) {
                return null; 
            }

            typeName = typeName + ", " + assemblyName;
 
            Type t = typeResolver.GetType(typeName);
            if (t == null) { 
                string[] typeParts = typeName.Split(new char[] {','}); 

                // Break up the assembly name from the rest of the assembly strong name. 
                // we try 1) FQN 2) FQN without a version 3) just the short name
                if (typeParts != null && typeParts.Length > 2) {
                    string partialName = typeParts[0].Trim();
 
                    for (int i = 1; i < typeParts.Length; ++i) {
                        string s = typeParts[i].Trim(); 
                        if (!s.StartsWith("Version=") && !s.StartsWith("version=")) { 
                            partialName = partialName + ", " + s;
                        } 
                    }
                    t = typeResolver.GetType(partialName);
                    if(t == null) {
                        t = typeResolver.GetType(typeParts[0].Trim()); 
                    }
                } 
            } 

            // Binder couldn't handle it, let the default loader take over. 
            return t;
        }
    }
 

    internal class AssemblyNamesTypeResolutionService : ITypeResolutionService { 
        private AssemblyName[] names; 
        private Hashtable cachedAssemblies;
        private Hashtable cachedTypes; 

        private static string NetFrameworkPath = Path.Combine(Environment.GetEnvironmentVariable("SystemRoot"), "Microsoft.Net\\Framework");

        internal AssemblyNamesTypeResolutionService(AssemblyName[] names) { 
            this.names = names;
        } 
 
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)] 
        public Assembly GetAssembly(AssemblyName name) {
            return GetAssembly(name, true);
        }
 
        //
        [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods")] 
        [ResourceExposure(ResourceScope.Machine)] 
        [ResourceConsumption(ResourceScope.Machine)]
        public Assembly GetAssembly(AssemblyName name, bool throwOnError) { 

            Assembly result = null;

            if (cachedAssemblies == null) { 
                cachedAssemblies = new Hashtable();
            } 
 
            if (cachedAssemblies.Contains(name)) {
                result = cachedAssemblies[name] as Assembly; 
            }

            if (result == null) {
                // try to load it first from the gac 
#pragma warning disable 0618
                //Although LoadWithPartialName is obsolete, we still have to call it: changing 
                //this would be breaking in cases where people edited their resource files by 
                //hand.
                result = Assembly.LoadWithPartialName(name.FullName); 
#pragma warning restore 0618
                if(result != null) {
                    cachedAssemblies[name] = result;
                } 
                else if (names != null) {
                    for(int i=0;i
        /// This is matching %windir%\Microsoft.NET\Framework*, so both 32bit and 64bit framework will be covered.
        ///  
        private bool IsNetFrameworkAssembly(string assemblyPath)
        { 
            return assemblyPath != null && assemblyPath.StartsWith(NetFrameworkPath, StringComparison.OrdinalIgnoreCase); 
        }
 
        public void ReferenceAssembly(AssemblyName name) {
            throw new NotSupportedException();
        }
 
    }
} 

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