Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / Resources / ResXResourceReader.cs / 1 / ResXResourceReader.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.Runtime.Serialization; 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.Collections.Specialized; using System.Runtime.CompilerServices; using System.Resources; using System.Xml; using System.ComponentModel.Design; using System.Globalization; #if SYSTEM_WEB using System.Web; // This is needed to access the SR resource strings #endif ////// /// ResX resource reader. /// [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 ResXResourceReader : IResourceReader { #else public class ResXResourceReader : IResourceReader { #endif //static readonly char[] SpecialChars = new char[]{' ', '\r', '\n'}; //IFormatter binaryFormatter = null; string fileName = null; TextReader reader = null; Stream stream = null; string fileContents = null; AssemblyName[] assemblyNames; string basePath; bool isReaderDirty = false; ITypeResolutionService typeResolver; IAliasResolver aliasResolver =null; ListDictionary resData = null; ListDictionary resMetadata = null; string resHeaderVersion = null; string resHeaderMimeType = null; string resHeaderReaderType = null; string resHeaderWriterType = null; bool useResXDataNodes = false; private ResXResourceReader(ITypeResolutionService typeResolver) { this.typeResolver = typeResolver; this.aliasResolver = new ReaderAliasResolver(); } private ResXResourceReader(AssemblyName[] assemblyNames) { this.assemblyNames = assemblyNames; this.aliasResolver = new ReaderAliasResolver(); } public ResXResourceReader(string fileName) : this(fileName, (ITypeResolutionService)null, (IAliasResolver)null) { } public ResXResourceReader(string fileName, ITypeResolutionService typeResolver) : this(fileName, typeResolver, (IAliasResolver)null) { } internal ResXResourceReader(string fileName, ITypeResolutionService typeResolver, IAliasResolver aliasResolver) { this.fileName = fileName; this.typeResolver = typeResolver; this.aliasResolver = aliasResolver; if(this.aliasResolver == null) { this.aliasResolver = new ReaderAliasResolver(); } } public ResXResourceReader(TextReader reader) : this(reader, (ITypeResolutionService)null, (IAliasResolver)null) { } public ResXResourceReader(TextReader reader, ITypeResolutionService typeResolver) : this(reader, typeResolver, (IAliasResolver)null) { } internal ResXResourceReader(TextReader reader, ITypeResolutionService typeResolver, IAliasResolver aliasResolver) { this.reader = reader; this.typeResolver = typeResolver; this.aliasResolver = aliasResolver; if(this.aliasResolver == null) { this.aliasResolver = new ReaderAliasResolver(); } } public ResXResourceReader(Stream stream) : this(stream, (ITypeResolutionService)null, (IAliasResolver)null) { } public ResXResourceReader(Stream stream, ITypeResolutionService typeResolver) : this(stream, typeResolver, (IAliasResolver)null) { } internal ResXResourceReader(Stream stream, ITypeResolutionService typeResolver, IAliasResolver aliasResolver) { this.stream = stream; this.typeResolver = typeResolver; this.aliasResolver = aliasResolver; if(this.aliasResolver == null) { this.aliasResolver = new ReaderAliasResolver(); } } public ResXResourceReader(Stream stream, AssemblyName[] assemblyNames) : this(stream, assemblyNames, (IAliasResolver)null){ } internal ResXResourceReader(Stream stream, AssemblyName[] assemblyNames, IAliasResolver aliasResolver) { this.stream = stream; this.assemblyNames = assemblyNames; this.aliasResolver = aliasResolver; if(this.aliasResolver == null) { this.aliasResolver = new ReaderAliasResolver(); } } public ResXResourceReader(TextReader reader, AssemblyName[] assemblyNames) : this(reader, assemblyNames, (IAliasResolver)null){ } internal ResXResourceReader(TextReader reader, AssemblyName[] assemblyNames, IAliasResolver aliasResolver) { this.reader = reader; this.assemblyNames = assemblyNames; this.aliasResolver = aliasResolver; if(this.aliasResolver == null) { this.aliasResolver = new ReaderAliasResolver(); } } public ResXResourceReader(string fileName, AssemblyName[] assemblyNames) : this(fileName, assemblyNames, (IAliasResolver)null){ } internal ResXResourceReader(string fileName, AssemblyName[] assemblyNames, IAliasResolver aliasResolver) { this.fileName = fileName; this.assemblyNames = assemblyNames; this.aliasResolver = aliasResolver; if(this.aliasResolver == null) { this.aliasResolver = new ReaderAliasResolver(); } } ///~ResXResourceReader() { Dispose(false); } /// /// /// BasePath for relatives filepaths with ResXFileRefs. /// public string BasePath { get { return basePath; } set { if(isReaderDirty) { throw new InvalidOperationException(SR.GetString(SR.InvalidResXBasePathOperation)); } basePath = value; } } #if UNUSED ////// Retrieves the resource data set. This will demand load it. /// private ListDictionary ResData { get { EnsureResData(); return resData; } } ////// Returns the typeResolver used to find types defined in the ResX contents. /// private ITypeResolutionService TypeResolver { get { return this.typeResolver; } } #endif ////// /// ResXFileRef's TypeConverter automatically unwraps it, creates the referenced /// object and returns it. This property gives the user control over whether this unwrapping should /// happen, or a ResXFileRef object should be returned. Default is true for backward compat and common case /// scenario. /// public bool UseResXDataNodes { get { return this.useResXDataNodes; } set { if(isReaderDirty) { throw new InvalidOperationException(SR.GetString(SR.InvalidResXBasePathOperation)); } this.useResXDataNodes = value; } } ////// /// Closes and files or streams being used by the reader. /// // NOTE: Part of IResourceReader - not protected by class level LinkDemand. public void Close() { ((IDisposable)this).Dispose(); } ////// // NOTE: Part of IDisposable - not protected by class level LinkDemand. void IDisposable.Dispose() { GC.SuppressFinalize(this); Dispose(true); } /// protected virtual void Dispose(bool disposing) { if (disposing) { if (fileName != null && stream != null) { stream.Close(); stream = null; } if (reader != null) { reader.Close(); reader = null; } } } private void SetupNameTable(XmlReader reader) { reader.NameTable.Add(ResXResourceWriter.TypeStr); reader.NameTable.Add(ResXResourceWriter.NameStr); reader.NameTable.Add(ResXResourceWriter.DataStr); reader.NameTable.Add(ResXResourceWriter.MetadataStr); reader.NameTable.Add(ResXResourceWriter.MimeTypeStr); reader.NameTable.Add(ResXResourceWriter.ValueStr); reader.NameTable.Add(ResXResourceWriter.ResHeaderStr); reader.NameTable.Add(ResXResourceWriter.VersionStr); reader.NameTable.Add(ResXResourceWriter.ResMimeTypeStr); reader.NameTable.Add(ResXResourceWriter.ReaderStr); reader.NameTable.Add(ResXResourceWriter.WriterStr); reader.NameTable.Add(ResXResourceWriter.BinSerializedObjectMimeType); reader.NameTable.Add(ResXResourceWriter.SoapSerializedObjectMimeType); reader.NameTable.Add(ResXResourceWriter.AssemblyStr); reader.NameTable.Add(ResXResourceWriter.AliasStr); } /// /// Demand loads the resource data. /// private void EnsureResData() { if (resData == null) { resData = new ListDictionary(); resMetadata = new ListDictionary(); XmlTextReader contentReader = null; try { // Read data in any which way if (fileContents != null) { contentReader = new XmlTextReader(new StringReader(fileContents)); } else if (reader != null) { contentReader = new XmlTextReader(reader); } else if (fileName != null || stream != null) { if (stream == null) { stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); } contentReader = new XmlTextReader(stream); } SetupNameTable(contentReader); contentReader.WhitespaceHandling = WhitespaceHandling.None; ParseXml(contentReader); } finally { if (fileName != null && stream != null) { stream.Close(); stream = null; } } } } ////// /// Creates a reader with the specified file contents. /// public static ResXResourceReader FromFileContents(string fileContents) { return FromFileContents(fileContents, (ITypeResolutionService)null); } ////// /// /// Creates a reader with the specified file contents. /// public static ResXResourceReader FromFileContents(string fileContents, ITypeResolutionService typeResolver) { ResXResourceReader result = new ResXResourceReader(typeResolver); result.fileContents = fileContents; return result; } ////// /// /// Creates a reader with the specified file contents. /// public static ResXResourceReader FromFileContents(string fileContents, AssemblyName[] assemblyNames) { ResXResourceReader result = new ResXResourceReader(assemblyNames); result.fileContents = fileContents; return result; } ////// // NOTE: Part of IEnumerable - not protected by class level LinkDemand. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// /// // NOTE: Part of IResourceReader - not protected by class level LinkDemand. public IDictionaryEnumerator GetEnumerator() { isReaderDirty = true; EnsureResData(); return resData.GetEnumerator(); } ///[To be supplied.] ////// /// Returns a dictionary enumerator that can be used to enumerate the public IDictionaryEnumerator GetMetadataEnumerator() { EnsureResData(); return resMetadata.GetEnumerator(); } ///elements in the .resx file. /// /// Attempts to return the line and column (Y, X) of the XML reader. /// private Point GetPosition(XmlReader reader) { Point pt = new Point(0, 0); IXmlLineInfo lineInfo = reader as IXmlLineInfo; if (lineInfo != null) { pt.Y = lineInfo.LineNumber; pt.X = lineInfo.LinePosition; } return pt; } private void ParseXml(XmlTextReader reader) { bool success = false; try { try { while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { string s = reader.LocalName; if (reader.LocalName.Equals(ResXResourceWriter.AssemblyStr)) { ParseAssemblyNode(reader, false); } else if (reader.LocalName.Equals(ResXResourceWriter.DataStr)) { ParseDataNode(reader, false); } else if (reader.LocalName.Equals(ResXResourceWriter.ResHeaderStr)) { ParseResHeaderNode(reader); } else if (reader.LocalName.Equals(ResXResourceWriter.MetadataStr)) { ParseDataNode(reader, true); } } } success = true; } catch (SerializationException se) { Point pt = GetPosition(reader); string newMessage = SR.GetString(SR.SerializationException, reader[ResXResourceWriter.TypeStr], pt.Y, pt.X, se.Message); XmlException xml = new XmlException(newMessage, se, pt.Y, pt.X); SerializationException newSe = new SerializationException(newMessage, xml); throw newSe; } catch (TargetInvocationException tie) { Point pt = GetPosition(reader); string newMessage = SR.GetString(SR.InvocationException, reader[ResXResourceWriter.TypeStr], pt.Y, pt.X, tie.InnerException.Message); XmlException xml = new XmlException(newMessage, tie.InnerException, pt.Y, pt.X); TargetInvocationException newTie = new TargetInvocationException(newMessage, xml); throw newTie; } catch (XmlException e) { throw new ArgumentException(SR.GetString(SR.InvalidResXFile, e.Message), e); } catch (Exception e) { if (ClientUtils.IsSecurityOrCriticalException(e)) { throw; } else { Point pt = GetPosition(reader); XmlException xmlEx = new XmlException(e.Message, e, pt.Y, pt.X); throw new ArgumentException(SR.GetString(SR.InvalidResXFile, xmlEx.Message), xmlEx); } } } finally { if (!success) { resData = null; resMetadata = null; } } bool validFile = false; if (object.Equals(resHeaderMimeType, ResXResourceWriter.ResMimeType)) { Type readerType = typeof(ResXResourceReader); Type writerType = typeof(ResXResourceWriter); string readerTypeName = resHeaderReaderType; string writerTypeName = resHeaderWriterType; if (readerTypeName != null &&readerTypeName.IndexOf(',') != -1) { readerTypeName = readerTypeName.Split(new char[] {','})[0].Trim(); } if (writerTypeName != null && writerTypeName.IndexOf(',') != -1) { writerTypeName = writerTypeName.Split(new char[] {','})[0].Trim(); } // Don't check validity, since our reader/writer classes are in System.Web.Compilation, // while the file format has them in System.Resources. #if SYSTEM_WEB validFile = true; #else if (readerTypeName != null && writerTypeName != null && readerTypeName.Equals(readerType.FullName) && writerTypeName.Equals(writerType.FullName)) { validFile = true; } #endif } if (!validFile) { resData = null; resMetadata = null; throw new ArgumentException(SR.GetString(SR.InvalidResXFileReaderWriterTypes)); } } private void ParseResHeaderNode(XmlReader reader) { string name = reader[ResXResourceWriter.NameStr]; if (name != null) { reader.ReadStartElement(); // The "1.1" schema requires the correct casing of the strings // in the resheader, however the "1.0" schema had a different // casing. By checking the Equals first, we should // see significant performance improvements. // if (object.Equals(name, ResXResourceWriter.VersionStr)) { if (reader.NodeType == XmlNodeType.Element) { resHeaderVersion = reader.ReadElementString(); } else { resHeaderVersion = reader.Value.Trim(); } } else if (object.Equals(name, ResXResourceWriter.ResMimeTypeStr)) { if (reader.NodeType == XmlNodeType.Element) { resHeaderMimeType = reader.ReadElementString(); } else { resHeaderMimeType = reader.Value.Trim(); } } else if (object.Equals(name, ResXResourceWriter.ReaderStr)) { if (reader.NodeType == XmlNodeType.Element) { resHeaderReaderType = reader.ReadElementString(); } else { resHeaderReaderType = reader.Value.Trim(); } } else if (object.Equals(name, ResXResourceWriter.WriterStr)) { if (reader.NodeType == XmlNodeType.Element) { resHeaderWriterType = reader.ReadElementString(); } else { resHeaderWriterType = reader.Value.Trim(); } } else { switch (name.ToLower(CultureInfo.InvariantCulture)) { case ResXResourceWriter.VersionStr: if (reader.NodeType == XmlNodeType.Element) { resHeaderVersion = reader.ReadElementString(); } else { resHeaderVersion = reader.Value.Trim(); } break; case ResXResourceWriter.ResMimeTypeStr: if (reader.NodeType == XmlNodeType.Element) { resHeaderMimeType = reader.ReadElementString(); } else { resHeaderMimeType = reader.Value.Trim(); } break; case ResXResourceWriter.ReaderStr: if (reader.NodeType == XmlNodeType.Element) { resHeaderReaderType = reader.ReadElementString(); } else { resHeaderReaderType = reader.Value.Trim(); } break; case ResXResourceWriter.WriterStr: if (reader.NodeType == XmlNodeType.Element) { resHeaderWriterType = reader.ReadElementString(); } else { resHeaderWriterType = reader.Value.Trim(); } break; } } } } #if UNUSED private string GetSimpleName(string typeName) { int indexStart = typeName.IndexOf(","); return typeName.Substring(0, indexStart); } #endif private void ParseAssemblyNode(XmlReader reader, bool isMetaData) { string alias = reader[ResXResourceWriter.AliasStr]; string typeName = reader[ResXResourceWriter.NameStr]; AssemblyName assemblyName = new AssemblyName(typeName); if (string.IsNullOrEmpty(alias)) { alias = assemblyName.Name; } aliasResolver.PushAlias(alias, assemblyName); } private void ParseDataNode(XmlTextReader reader, bool isMetaData) { DataNodeInfo nodeInfo = new DataNodeInfo(); nodeInfo.Name = reader[ResXResourceWriter.NameStr]; string typeName = reader[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 = reader[ResXResourceWriter.TypeStr]; } nodeInfo.MimeType = reader[ResXResourceWriter.MimeTypeStr]; bool finishedReadingDataNode = false; nodeInfo.ReaderPosition = GetPosition(reader); while(!finishedReadingDataNode && reader.Read()) { if(reader.NodeType == XmlNodeType.EndElement && ( reader.LocalName.Equals(ResXResourceWriter.DataStr) || reader.LocalName.Equals(ResXResourceWriter.MetadataStr) )) { // we just found , quit or finishedReadingDataNode = true; } else { // could be aor a if (reader.NodeType == XmlNodeType.Element) { if (reader.Name.Equals(ResXResourceWriter.ValueStr)) { WhitespaceHandling oldValue = reader.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... reader.WhitespaceHandling = WhitespaceHandling.Significant; nodeInfo.ValueData = reader.ReadString(); } finally { reader.WhitespaceHandling = oldValue; } } else if (reader.Name.Equals(ResXResourceWriter.CommentStr)) { nodeInfo.Comment = reader.ReadString(); } } else { // weird, no tag, just the inside of as text nodeInfo.ValueData = reader.Value.Trim(); } } } if (nodeInfo.Name==null) { throw new ArgumentException(SR.GetString(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); } } } private string GetAliasFromTypeName(string typeName) { int indexStart = typeName.IndexOf(","); return typeName.Substring(indexStart + 2); } private string GetTypeFromTypeName(string typeName) { int indexStart = typeName.IndexOf(","); return typeName.Substring(0, indexStart); } private sealed class ReaderAliasResolver : IAliasResolver { private Hashtable cachedAliases; internal ReaderAliasResolver() { this.cachedAliases = new Hashtable(); } public AssemblyName ResolveAlias(string alias) { AssemblyName result = null; if(cachedAliases != null) { result = (AssemblyName)cachedAliases[alias]; } return result; } public void PushAlias(string alias, AssemblyName name) { if (this.cachedAliases != null && !string.IsNullOrEmpty(alias)) { cachedAliases[alias] = name; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ErrorWebPart.cs
- ZipIORawDataFileBlock.cs
- Baml2006ReaderFrame.cs
- UserNameSecurityTokenAuthenticator.cs
- FrameworkRichTextComposition.cs
- CharacterBuffer.cs
- EntitySetDataBindingList.cs
- WindowsListViewGroupHelper.cs
- StringValidatorAttribute.cs
- IListConverters.cs
- XmlSchemaAttributeGroup.cs
- DataGridRowDetailsEventArgs.cs
- SpanIndex.cs
- XmlReflectionImporter.cs
- CodeMethodReturnStatement.cs
- HtmlControl.cs
- VectorCollectionConverter.cs
- XsltContext.cs
- WorkflowServiceBuildProvider.cs
- CodeIdentifier.cs
- PenThreadWorker.cs
- PrinterResolution.cs
- UserControlParser.cs
- ExpressionBinding.cs
- PrimarySelectionGlyph.cs
- ControlPaint.cs
- TextBreakpoint.cs
- XXXOnTypeBuilderInstantiation.cs
- TextDecorationLocationValidation.cs
- IsolatedStorageException.cs
- SplineKeyFrames.cs
- ReadOnlyDataSourceView.cs
- ExpressionBuilder.cs
- FormatConvertedBitmap.cs
- DbReferenceCollection.cs
- ConnectionInterfaceCollection.cs
- RawStylusActions.cs
- FullTextState.cs
- SuppressMessageAttribute.cs
- Panel.cs
- IsolationInterop.cs
- AdapterSwitches.cs
- ActivityLocationReferenceEnvironment.cs
- SqlDataSource.cs
- ProcessModuleCollection.cs
- ControlBuilderAttribute.cs
- DesignerLoader.cs
- FileSystemEventArgs.cs
- ClientConvert.cs
- Typeface.cs
- CounterNameConverter.cs
- UrlAuthorizationModule.cs
- TreeViewItemAutomationPeer.cs
- StringFreezingAttribute.cs
- ExceptionRoutedEventArgs.cs
- BufferedStream.cs
- WebResponse.cs
- StrongNameKeyPair.cs
- BooleanAnimationBase.cs
- SmiTypedGetterSetter.cs
- QueryStringConverter.cs
- CryptoHandle.cs
- ChangeNode.cs
- XPathMessageFilterElementComparer.cs
- ExpressionValueEditor.cs
- Context.cs
- FrameworkContentElement.cs
- HtmlForm.cs
- DeclarativeExpressionConditionDeclaration.cs
- ListChangedEventArgs.cs
- _AutoWebProxyScriptHelper.cs
- ItemAutomationPeer.cs
- RootProjectionNode.cs
- ServiceProviders.cs
- DirectoryNotFoundException.cs
- TableLayoutStyleCollection.cs
- IndexOutOfRangeException.cs
- UserNamePasswordClientCredential.cs
- LayoutTable.cs
- _SslSessionsCache.cs
- XmlnsDefinitionAttribute.cs
- HighlightComponent.cs
- CreateUserWizardStep.cs
- MultiplexingFormatMapping.cs
- CodeDOMUtility.cs
- ObfuscateAssemblyAttribute.cs
- PointKeyFrameCollection.cs
- Executor.cs
- InternalConfigHost.cs
- ServiceModelConfigurationSection.cs
- MouseEventArgs.cs
- DataPagerField.cs
- MenuItemStyle.cs
- XomlCompilerParameters.cs
- SqlTypeConverter.cs
- SqlDataAdapter.cs
- ResourcesGenerator.cs
- PageBreakRecord.cs
- EmptyStringExpandableObjectConverter.cs
- HMACSHA1.cs