/// <summary>
        ///     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.
        /// </summary>
        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);
            }
        }
        /// <summary>
        ///     Adds a string resource to the resources.
        /// </summary>
        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);
        }
Example #3
0
        // <summary>
        // this is a deep clone
        //</summary>
        internal ResXDataNode DeepClone()
        {
            ResXDataNode result = new ResXDataNode
            {
                // nodeinfo is just made up of immutable objects, we don't need to clone it
                nodeInfo            = nodeInfo?.Clone(),
                name                = name,
                comment             = comment,
                typeName            = typeName,
                fileRefFullPath     = fileRefFullPath,
                fileRefType         = fileRefType,
                fileRefTextEncoding = fileRefTextEncoding,
                value               = value,
                fileRef             = fileRef?.Clone(),
                typeNameConverter   = typeNameConverter
            };

            // we don't clone the value, because we don't know how
            return(result);
        }
        private void ParseDataNode(XmlTextReader nodeReader, bool isMetaData)
        {
            DataNodeInfo nodeInfo = new DataNodeInfo();

            nodeInfo.Name = nodeReader[ResXResourceWriter.NameStr];
            string typeName = nodeReader[ResXResourceWriter.TypeStr];

            string       alias        = null;
            AssemblyName assemblyName = null;

            if (!string.IsNullOrEmpty(typeName))
            {
                alias = GetAliasFromTypeName(typeName);
            }

            if (!string.IsNullOrEmpty(alias))
            {
                assemblyName = aliasResolver.ResolveAlias(alias);
            }

            if (assemblyName != null)
            {
                nodeInfo.TypeName = GetTypeFromTypeName(typeName) + ", " + assemblyName.FullName;
            }
            else
            {
                nodeInfo.TypeName = nodeReader[ResXResourceWriter.TypeStr];
            }

            nodeInfo.MimeType = nodeReader[ResXResourceWriter.MimeTypeStr];

            bool finishedReadingDataNode = false;

            nodeInfo.ReaderPosition = GetPosition(nodeReader);
            while (!finishedReadingDataNode && nodeReader.Read())
            {
                if (nodeReader.NodeType == XmlNodeType.EndElement &&
                    (nodeReader.LocalName.Equals(ResXResourceWriter.DataStr) ||
                     nodeReader.LocalName.Equals(ResXResourceWriter.MetadataStr)))
                {
                    // we just found </data>, quit or </metadata>
                    finishedReadingDataNode = true;
                }
                else
                {
                    // could be a <value> or a <comment>
                    if (nodeReader.NodeType == XmlNodeType.Element)
                    {
                        if (nodeReader.Name.Equals(ResXResourceWriter.ValueStr))
                        {
                            WhitespaceHandling oldValue = nodeReader.WhitespaceHandling;
                            try
                            {
                                // based on the documentation at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemxmlxmltextreaderclasswhitespacehandlingtopic.asp
                                // this is ok because:
                                // "Because the XmlTextReader does not have DTD information available to it,
                                // SignificantWhitepsace nodes are only returned within the an xml:space='preserve' scope."
                                // the xml:space would not be present for anything else than string and char (see ResXResourceWriter)
                                // so this would not cause any breaking change while reading data from Everett (we never outputed
                                // xml:space then) or from whidbey that is not specifically either a string or a char.
                                // However please note that manually editing a resx file in Everett and in Whidbey because of the addition
                                // of xml:space=preserve might have different consequences...
                                nodeReader.WhitespaceHandling = WhitespaceHandling.Significant;
                                nodeInfo.ValueData            = nodeReader.ReadString();
                            }
                            finally
                            {
                                nodeReader.WhitespaceHandling = oldValue;
                            }
                        }
                        else if (nodeReader.Name.Equals(ResXResourceWriter.CommentStr))
                        {
                            nodeInfo.Comment = nodeReader.ReadString();
                        }
                    }
                    else
                    {
                        // weird, no <xxxx> tag, just the inside of <data> as text
                        nodeInfo.ValueData = nodeReader.Value.Trim();
                    }
                }
            }

            if (nodeInfo.Name == null)
            {
                throw new ArgumentException(string.Format(SR.InvalidResXResourceNoName, nodeInfo.ValueData));
            }

            ResXDataNode dataNode = new ResXDataNode(nodeInfo, BasePath);

            if (UseResXDataNodes)
            {
                resData[nodeInfo.Name] = dataNode;
            }
            else
            {
                IDictionary data = (isMetaData ? resMetadata : resData);
                if (assemblyNames == null)
                {
                    data[nodeInfo.Name] = dataNode.GetValue(typeResolver);
                }
                else
                {
                    data[nodeInfo.Name] = dataNode.GetValue(assemblyNames);
                }
            }
        }