protected override void Dispose(bool disposing) { if (Reader == null) { return; } if (disposing) { lock (Reader) { _resCache = null; if (_defaultReader != null) { _defaultReader.Close(); _defaultReader = null; } _caseInsensitiveTable = null; // Set Reader to null to avoid a race in GetObject. base.Dispose(disposing); } } else { // Just to make sure we always clear these fields in the future... _resCache = null; _caseInsensitiveTable = null; _defaultReader = null; base.Dispose(disposing); } }
internal RuntimeResourceSet(string fileName) : base(false) { _resCache = new Dictionary<string, ResourceLocator>(FastResourceComparer.Default); Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); _defaultReader = new ResourceReader(stream, _resCache, false); Reader = _defaultReader; }
private IDictionaryEnumerator GetEnumeratorHelper() { ResourceReader?reader = _defaultReader; if (reader is null) { throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet); } return(reader.GetEnumerator()); }
internal RuntimeResourceSet(IResourceReader reader) : // explicitly do not call IResourceReader constructor since it caches all resources // the purpose of RuntimeResourceSet is to lazily load and cache. base() { if (reader == null) throw new ArgumentNullException(nameof(reader)); _defaultReader = reader as DeserializingResourceReader ?? throw new ArgumentException(SR.Format(SR.NotSupported_WrongResourceReader_Type, reader.GetType()), nameof(reader)); _resCache = new Dictionary<string, ResourceLocator>(FastResourceComparer.Default); // in the CoreLib version RuntimeResourceSet creates ResourceReader and passes this in, // in the custom case ManifestBasedResourceReader creates the ResourceReader and passes it in // so we must initialize the cache here. _defaultReader._resCache = _resCache; }
protected override void Dispose(bool disposing) { if (_defaultReader is null) { return; } if (disposing) { _defaultReader?.Close(); } _defaultReader = null; _resCache = null; _caseInsensitiveTable = null; base.Dispose(disposing); }
private object?GetObject(string key, bool ignoreCase, bool isString) { if (key == null) { throw new ArgumentNullException(nameof(key)); } ResourceReader?reader = _defaultReader; Dictionary <string, ResourceLocator>?cache = _resCache; if (reader is null || cache is null) { throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet); } object? value; ResourceLocator resEntry; lock (cache) { // Find the offset within the data section int dataPos; if (cache.TryGetValue(key, out resEntry)) { value = resEntry.Value; if (value != null) { return(value); } // When data type cannot be cached dataPos = resEntry.DataPosition; return(isString ? reader.LoadString(dataPos) : reader.LoadObject(dataPos, out _)); } dataPos = reader.FindPosForResource(key); if (dataPos >= 0) { value = ReadValue(reader, dataPos, isString, out resEntry); cache[key] = resEntry; return(value); } } if (!ignoreCase) { return(null); } // We haven't found the particular resource we're looking for // and may have to search for it in a case-insensitive way. bool initialize = false; Dictionary <string, ResourceLocator>?caseInsensitiveTable = _caseInsensitiveTable; if (caseInsensitiveTable == null) { caseInsensitiveTable = new Dictionary <string, ResourceLocator>(StringComparer.OrdinalIgnoreCase); initialize = true; } lock (caseInsensitiveTable) { if (initialize) { ResourceReader.ResourceEnumerator en = reader.GetEnumeratorInternal(); while (en.MoveNext()) { // The resource key must be read before the data position. string currentKey = (string)en.Key; ResourceLocator resLoc = new ResourceLocator(en.DataPosition, null); caseInsensitiveTable.Add(currentKey, resLoc); } _caseInsensitiveTable = caseInsensitiveTable; } if (!caseInsensitiveTable.TryGetValue(key, out resEntry)) { return(null); } if (resEntry.Value != null) { return(resEntry.Value); } value = ReadValue(reader, resEntry.DataPosition, isString, out resEntry); if (resEntry.Value != null) { caseInsensitiveTable[key] = resEntry; } } return(value); }
internal RuntimeResourceSet(Stream stream, bool permitDeserialization = false) : base(false) { _resCache = new Dictionary <string, ResourceLocator>(FastResourceComparer.Default); _defaultReader = new ResourceReader(stream, _resCache, permitDeserialization); }