コード例 #1
0
        private static object?ReadValue(ResourceReader reader, int dataPos, bool isString, out ResourceLocator locator)
        {
            object?          value;
            ResourceTypeCode typeCode;

            // Normally calling LoadString or LoadObject requires
            // taking a lock.  Note that in this case, we took a
            // lock before calling this method.
            if (isString)
            {
                value    = reader.LoadString(dataPos);
                typeCode = ResourceTypeCode.String;
            }
            else
            {
                value = reader.LoadObject(dataPos, out typeCode);
            }

            locator = new ResourceLocator(dataPos, ResourceLocator.CanCache(typeCode) ? value : null);
            return(value);
        }
コード例 #2
0
 private object? ResolveResourceLocator(ResourceLocator resLocation, string key, Dictionary<string, ResourceLocator> copyOfCache, bool keyInWrongCase)
 {
     // We need to explicitly resolve loosely linked manifest
     // resources, and we need to resolve ResourceLocators with null objects.
     object? value = resLocation.Value;
     if (value == null)
     {
         ResourceTypeCode typeCode;
         lock (Reader)
         {
             Debug.Assert(_defaultReader != null);
             value = _defaultReader.LoadObject(resLocation.DataPosition, out typeCode);
         }
         if (!keyInWrongCase && ResourceLocator.CanCache(typeCode))
         {
             resLocation.Value = value;
             copyOfCache[key] = resLocation;
         }
     }
     return value;
 }
コード例 #3
0
        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);
        }
コード例 #4
0
        private object?GetObject(string key, bool ignoreCase, bool isString)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (Reader == null || _resCache == null)
            {
                throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet);
            }

            object?         value = null;
            ResourceLocator resLocation;

            lock (Reader)
            {
                if (Reader == null)
                {
                    throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet);
                }

                if (_defaultReader != null)
                {
                    // Find the offset within the data section
                    int dataPos = -1;
                    if (_resCache.TryGetValue(key, out resLocation))
                    {
                        value   = resLocation.Value;
                        dataPos = resLocation.DataPosition;
                    }

                    if (dataPos == -1 && value == null)
                    {
                        dataPos = _defaultReader.FindPosForResource(key);
                    }

                    if (dataPos != -1 && value == null)
                    {
                        Debug.Assert(dataPos >= 0, "data section offset cannot be negative!");
                        // Normally calling LoadString or LoadObject requires
                        // taking a lock.  Note that in this case, we took a
                        // lock on the entire RuntimeResourceSet, which is
                        // sufficient since we never pass this ResourceReader
                        // to anyone else.
                        ResourceTypeCode typeCode;
                        if (isString)
                        {
                            value    = _defaultReader.LoadString(dataPos);
                            typeCode = ResourceTypeCode.String;
                        }
                        else
                        {
                            value = _defaultReader.LoadObject(dataPos, out typeCode);
                        }

                        resLocation = new ResourceLocator(dataPos, (ResourceLocator.CanCache(typeCode)) ? value : null);
                        lock (_resCache)
                        {
                            _resCache[key] = resLocation;
                        }
                    }

                    if (value != null || !ignoreCase)
                    {
                        return(value);  // may be null
                    }
                }  // if (_defaultReader != null)

                // At this point, we either don't have our default resource reader
                // or we haven't found the particular resource we're looking for
                // and may have to search for it in a case-insensitive way.
                if (!_haveReadFromReader)
                {
                    // If necessary, init our case insensitive hash table.
                    if (ignoreCase && _caseInsensitiveTable == null)
                    {
                        _caseInsensitiveTable = new Dictionary <string, ResourceLocator>(StringComparer.OrdinalIgnoreCase);
                    }

                    if (_defaultReader == null)
                    {
                        IDictionaryEnumerator en = Reader.GetEnumerator();
                        while (en.MoveNext())
                        {
                            DictionaryEntry entry   = en.Entry;
                            string          readKey = (string)entry.Key;
                            ResourceLocator resLoc  = new ResourceLocator(-1, entry.Value);
                            _resCache.Add(readKey, resLoc);
                            if (ignoreCase)
                            {
                                Debug.Assert(_caseInsensitiveTable != null);
                                _caseInsensitiveTable.Add(readKey, resLoc);
                            }
                        }
                        // Only close the reader if it is NOT our default one,
                        // since we need it around to resolve ResourceLocators.
                        if (!ignoreCase)
                        {
                            Reader.Close();
                        }
                    }
                    else
                    {
                        Debug.Assert(ignoreCase, "This should only happen for case-insensitive lookups");
                        Debug.Assert(_caseInsensitiveTable != null);
                        ResourceReader.ResourceEnumerator en = _defaultReader.GetEnumeratorInternal();
                        while (en.MoveNext())
                        {
                            // Note: Always ask for the resource key before the data position.
                            string          currentKey = (string)en.Key;
                            int             dataPos    = en.DataPosition;
                            ResourceLocator resLoc     = new ResourceLocator(dataPos, null);
                            _caseInsensitiveTable.Add(currentKey, resLoc);
                        }
                    }
                    _haveReadFromReader = true;
                }
                object?obj            = null;
                bool   found          = false;
                bool   keyInWrongCase = false;
                if (_defaultReader != null)
                {
                    if (_resCache.TryGetValue(key, out resLocation))
                    {
                        found = true;
                        obj   = ResolveResourceLocator(resLocation, key, _resCache, keyInWrongCase);
                    }
                }
                if (!found && ignoreCase)
                {
                    Debug.Assert(_caseInsensitiveTable != null);
                    if (_caseInsensitiveTable.TryGetValue(key, out resLocation))
                    {
                        found          = true;
                        keyInWrongCase = true;
                        obj            = ResolveResourceLocator(resLocation, key, _resCache, keyInWrongCase);
                    }
                }
                return(obj);
            } // lock(Reader)
        }