Пример #1
0
        [SecuritySafeCritical]  // Asserts permission to create & delete a temp file.
        public void Generate()
        {
            if (_resourceList == null)
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceWriterSaved"));
            }

            BinaryWriter  bw        = new BinaryWriter(_output, Encoding.UTF8);
            List <String> typeNames = new List <String>();

            // Write out the ResourceManager header
            // Write out magic number
            bw.Write(ResourceManager.MagicNumber);

            // Write out ResourceManager header version number
            bw.Write(ResourceManager.HeaderVersionNumber);

            MemoryStream resMgrHeaderBlob = new MemoryStream(240);
            BinaryWriter resMgrHeaderPart = new BinaryWriter(resMgrHeaderBlob);

            // Write out class name of IResourceReader capable of handling
            // this file.
            resMgrHeaderPart.Write(MultitargetingHelpers.GetAssemblyQualifiedName(typeof(ResourceReader), typeConverter));

            // Write out class name of the ResourceSet class best suited to
            // handling this file.
            // This needs to be the same even with multi-targeting. It's the
            // full name -- not the ----sembly qualified name.
            resMgrHeaderPart.Write(ResourceManager.ResSetTypeName);
            resMgrHeaderPart.Flush();

            // Write number of bytes to skip over to get past ResMgr header
            bw.Write((int)resMgrHeaderBlob.Length);

            // Write the rest of the ResMgr header
            bw.Write(resMgrHeaderBlob.GetBuffer(), 0, (int)resMgrHeaderBlob.Length);
            // End ResourceManager header


            // Write out the RuntimeResourceSet header
            // Version number
            bw.Write(RuntimeResourceSet.Version);
#if RESOURCE_FILE_FORMAT_DEBUG
            // Write out a tag so we know whether to enable or disable
            // debugging support when reading the file.
            bw.Write("***DEBUG***");
#endif

            // number of resources
            int numResources = _resourceList.Count;
            if (_preserializedData != null)
            {
                numResources += _preserializedData.Count;
            }
            bw.Write(numResources);

            // Store values in temporary streams to write at end of file.
            int[]        nameHashes    = new int[numResources];
            int[]        namePositions = new int[numResources];
            int          curNameNumber = 0;
            MemoryStream nameSection   = new MemoryStream(numResources * AverageNameSize);
            BinaryWriter names         = new BinaryWriter(nameSection, Encoding.Unicode);

            // The data section can be very large, and worse yet, we can grow the byte[] used
            // for the data section repeatedly.  When using large resources like ~100 images,
            // this can lead to both a fragmented large object heap as well as allocating about
            // 2-3x of our storage needs in extra overhead.  Using a temp file can avoid this.
            // Assert permission to get a temp file name, which requires two permissions.
            // Additionally, we may be running under an account that doesn't have permission to
            // write to the temp directory (enforced via a Windows ACL).  Fall back to a MemoryStream.
            Stream dataSection = null;  // Either a FileStream or a MemoryStream
            String tempFile    = null;
#if !DISABLE_CAS_USE
            PermissionSet permSet = new PermissionSet(PermissionState.None);
            permSet.AddPermission(new EnvironmentPermission(PermissionState.Unrestricted));
            permSet.AddPermission(new FileIOPermission(PermissionState.Unrestricted));
#endif
            try {
#if !DISABLE_CAS_USE
                permSet.Assert();
#endif
                tempFile = Path.GetTempFileName();
                File.SetAttributes(tempFile, FileAttributes.Temporary | FileAttributes.NotContentIndexed);
                // Explicitly opening with FileOptions.DeleteOnClose to avoid complicated File.Delete
                // (safe from ----s w/ antivirus software, etc)
                dataSection = new FileStream(tempFile, FileMode.Open, FileAccess.ReadWrite, FileShare.Read,
                                             4096, FileOptions.DeleteOnClose | FileOptions.SequentialScan);
            }
            catch (UnauthorizedAccessException) {
                // In case we're running under an account that can't access a temp directory.
                dataSection = new MemoryStream();
            }
            catch (IOException) {
                // In case Path.GetTempFileName fails because no unique file names are available
                dataSection = new MemoryStream();
            }
            finally {
#if !DISABLE_CAS_USE
                PermissionSet.RevertAssert();
#endif
            }

            using (dataSection) {
                BinaryWriter data = new BinaryWriter(dataSection, Encoding.UTF8);
#if FEATURE_SERIALIZATION
                IFormatter objFormatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File | StreamingContextStates.Persistence));
#endif // FEATURE_SERIALIZATION

#if RESOURCE_FILE_FORMAT_DEBUG
                // Write NAMES right before the names section.
                names.Write(new byte[] { (byte)'N', (byte)'A', (byte)'M', (byte)'E', (byte)'S', (byte)'-', (byte)'-', (byte)'>' });

                // Write DATA at the end of the name table section.
                data.Write(new byte[] { (byte)'D', (byte)'A', (byte)'T', (byte)'A', (byte)'-', (byte)'-', (byte)'-', (byte)'>' });
#endif

                // We've stored our resources internally in a Hashtable, which
                // makes no guarantees about the ordering while enumerating.
                // While we do our own sorting of the resource names based on their
                // hash values, that's only sorting the nameHashes and namePositions
                // arrays.  That's all that is strictly required for correctness,
                // but for ease of generating a patch in the future that
                // modifies just .resources files, we should re-sort them.

                SortedList sortedResources = new SortedList(_resourceList, FastResourceComparer.Default);
                if (_preserializedData != null)
                {
                    foreach (KeyValuePair <String, PrecannedResource> entry in _preserializedData)
                    {
                        sortedResources.Add(entry.Key, entry.Value);
                    }
                }

                IDictionaryEnumerator items = sortedResources.GetEnumerator();
                // Write resource name and position to the file, and the value
                // to our temporary buffer.  Save Type as well.
                while (items.MoveNext())
                {
                    nameHashes[curNameNumber]      = FastResourceComparer.HashFunction((String)items.Key);
                    namePositions[curNameNumber++] = (int)names.Seek(0, SeekOrigin.Current);
                    names.Write((String)items.Key);                     // key
                    names.Write((int)data.Seek(0, SeekOrigin.Current)); // virtual offset of value.
#if RESOURCE_FILE_FORMAT_DEBUG
                    names.Write((byte)'*');
#endif
                    Object           value    = items.Value;
                    ResourceTypeCode typeCode = FindTypeCode(value, typeNames);

                    // Write out type code
                    Write7BitEncodedInt(data, (int)typeCode);

                    // Write out value
                    PrecannedResource userProvidedResource = value as PrecannedResource;
                    if (userProvidedResource != null)
                    {
                        data.Write(userProvidedResource.Data);
                    }
                    else
                    {
#if FEATURE_SERIALIZATION
                        WriteValue(typeCode, value, data, objFormatter);
#else
                        WriteValue(typeCode, value, data);
#endif
                    }

#if RESOURCE_FILE_FORMAT_DEBUG
                    data.Write(new byte[] { (byte)'S', (byte)'T', (byte)'O', (byte)'P' });
#endif
                }

                // At this point, the ResourceManager header has been written.
                // Finish RuntimeResourceSet header
                //   Write size & contents of class table
                bw.Write(typeNames.Count);
                for (int i = 0; i < typeNames.Count; i++)
                {
                    bw.Write(typeNames[i]);
                }

                // Write out the name-related items for lookup.
                //  Note that the hash array and the namePositions array must
                //  be sorted in parallel.
                Array.Sort(nameHashes, namePositions);

                //  Prepare to write sorted name hashes (alignment fixup)
                //   Note: For 64-bit machines, these MUST be aligned on 8 byte
                //   boundaries!  Pointers on IA64 must be aligned!  And we'll
                //   run faster on X86 machines too.
                bw.Flush();
                int alignBytes = ((int)bw.BaseStream.Position) & 7;
                if (alignBytes > 0)
                {
                    for (int i = 0; i < 8 - alignBytes; i++)
                    {
                        bw.Write("PAD"[i % 3]);
                    }
                }

                //  Write out sorted name hashes.
                //   Align to 8 bytes.
                Contract.Assert((bw.BaseStream.Position & 7) == 0, "ResourceWriter: Name hashes array won't be 8 byte aligned!  Ack!");
#if RESOURCE_FILE_FORMAT_DEBUG
                bw.Write(new byte[] { (byte)'H', (byte)'A', (byte)'S', (byte)'H', (byte)'E', (byte)'S', (byte)'-', (byte)'>' });
#endif
                foreach (int hash in nameHashes)
                {
                    bw.Write(hash);
                }
#if RESOURCE_FILE_FORMAT_DEBUG
                Console.Write("Name hashes: ");
                foreach (int hash in nameHashes)
                {
                    Console.Write(hash.ToString("x") + "  ");
                }
                Console.WriteLine();
#endif

                //  Write relative positions of all the names in the file.
                //   Note: this data is 4 byte aligned, occuring immediately
                //   after the 8 byte aligned name hashes (whose length may
                //   potentially be odd).
                Contract.Assert((bw.BaseStream.Position & 3) == 0, "ResourceWriter: Name positions array won't be 4 byte aligned!  Ack!");
#if RESOURCE_FILE_FORMAT_DEBUG
                bw.Write(new byte[] { (byte)'P', (byte)'O', (byte)'S', (byte)'-', (byte)'-', (byte)'-', (byte)'-', (byte)'>' });
#endif
                foreach (int pos in namePositions)
                {
                    bw.Write(pos);
                }
#if RESOURCE_FILE_FORMAT_DEBUG
                Console.Write("Name positions: ");
                foreach (int pos in namePositions)
                {
                    Console.Write(pos.ToString("x") + "  ");
                }
                Console.WriteLine();
#endif

                // Flush all BinaryWriters to their underlying streams.
                bw.Flush();
                names.Flush();
                data.Flush();

                // Write offset to data section
                int startOfDataSection = (int)(bw.Seek(0, SeekOrigin.Current) + nameSection.Length);
                startOfDataSection += 4;  // We're writing an int to store this data, adding more bytes to the header
                BCLDebug.Log("RESMGRFILEFORMAT", "Generate: start of DataSection: 0x" + startOfDataSection.ToString("x", CultureInfo.InvariantCulture) + "  nameSection length: " + nameSection.Length);
                bw.Write(startOfDataSection);

                // Write name section.
                bw.Write(nameSection.GetBuffer(), 0, (int)nameSection.Length);
                names.Close();

                // Write data section.
                Contract.Assert(startOfDataSection == bw.Seek(0, SeekOrigin.Current), "ResourceWriter::Generate - start of data section is wrong!");
                dataSection.Position = 0;
                dataSection.CopyTo(bw.BaseStream);
                data.Close();
            } // using(dataSection)  <--- Closes dataSection, which was opened w/ FileOptions.DeleteOnClose
            bw.Flush();

            // Indicate we've called Generate
            _resourceList = null;
        }
Пример #2
0
        // From a name, finds the associated virtual offset for the data.
        // This does a binary search through the names.
        internal int FindPosForResource(String name)
        {
            BCLDebug.Assert(_store != null, "ResourceReader is closed!");
            int hash = FastResourceComparer.GetHashCode(name);

            BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for " + name + "  hash: " + hash.ToString("x"));
            // Binary search over the hashes.  Use the _namePositions array to
            // determine where they exist in the underlying stream.
            int  lo      = 0;
            int  hi      = _numResources - 1;
            int  index   = -1;
            bool success = false;

            while (lo <= hi)
            {
                index = (lo + hi) >> 1;
                // Do NOT use subtraction here, since it will wrap for large
                // negative numbers.
                //int c = _nameHashes[index].CompareTo(hash);
                int currentHash = GetNameHash(index);
                int c;
                if (currentHash == hash)
                {
                    c = 0;
                }
                else if (currentHash < hash)
                {
                    c = -1;
                }
                else
                {
                    c = 1;
                }
                //BCLDebug.Log("RESMGRFILEFORMAT", "  Probing index "+index+"  lo: "+lo+"  hi: "+hi+"  c: "+c);
                if (c == 0)
                {
                    success = true;
                    break;
                }
                if (c < 0)
                {
                    lo = index + 1;
                }
                else
                {
                    hi = index - 1;
                }
            }
            if (!success)
            {
#if RESOURCE_FILE_FORMAT_DEBUG
                lock (this) {
                    _store.BaseStream.Seek(_nameSectionOffset + GetNamePosition(index), SeekOrigin.Begin);
                    String lastReadString = _store.ReadString();
                }
                BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for " + name + " failed.  i: " + index + "  lo: " + lo + "  hi: " + hi + "  last read string: \"" + lastReadString + "\"");
#endif
                return(-1);
            }

            // index is the location in our hash array that corresponds with a
            // value in the namePositions array.
            // There could be collisions in our hash function.  Check on both sides
            // of index to find the range of hash values that are equal to the
            // target hash value.
            if (lo != index)
            {
                lo = index;
                while (lo > 0 && GetNameHash(lo - 1) == hash)
                {
                    lo--;
                }
            }
            if (hi != index)
            {
                hi = index;
                while (hi < _numResources && GetNameHash(hi + 1) == hash)
                {
                    hi++;
                }
            }

            lock (this) {
                for (int i = lo; i <= hi; i++)
                {
                    _store.BaseStream.Seek(_nameSectionOffset + GetNamePosition(i), SeekOrigin.Begin);
                    if (CompareStringEqualsName(name))
                    {
                        int dataPos = _store.ReadInt32();
                        BCLDebug.Assert(dataPos >= 0 || dataPos < _store.BaseStream.Length - _dataSectionOffset, "Data section relative offset is out of the bounds of the data section!  dataPos: " + dataPos);
                        return(dataPos);
                    }
                }
            }
            BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for " + name + ": Found a hash collision, HOWEVER, neither of these collided values equaled the given string.");
            return(-1);
        }
Пример #3
0
 public int GetHashCode(String key)
 {
     return(FastResourceComparer.HashFunction(key));
 }
Пример #4
0
        // Implements IHashCodeProvider too, due to Hashtable requirements.
        public int GetHashCode(object key)
        {
            string s = (string)key;

            return(FastResourceComparer.HashFunction(s));
        }
Пример #5
0
 // Implements IHashCodeProvider too, due to Hashtable requirements.
 public int GetHashCode(Object key)
 {
     String s = (String) key;
     return FastResourceComparer.HashFunction(s);
 }
Пример #6
0
        // After calling AddResource, Generate() writes out all resources to the
        // output stream in the system default format.
        // If an exception occurs during object serialization or during IO,
        // the .resources file is closed and deleted, since it is most likely
        // invalid.
        public void Generate()
        {
            if (_resourceList == null)
            {
                throw new InvalidOperationException(SR.InvalidOperation_ResourceWriterSaved);
            }

            BinaryWriter bw = new BinaryWriter(_output, Encoding.UTF8);

            // Write out the ResourceManager header
            // Write out magic number
            bw.Write(ResourceManagerMagicNumber);

            // Write out ResourceManager header version number
            bw.Write(ResourceManagerHeaderVersionNumber);

            MemoryStream resMgrHeaderBlob = new MemoryStream(240);
            BinaryWriter resMgrHeaderPart = new BinaryWriter(resMgrHeaderBlob);

            // Write out class name of IResourceReader capable of handling
            // this file.
            resMgrHeaderPart.Write(ResourceReaderFullyQualifiedName);

            // Write out class name of the ResourceSet class best suited to
            // handling this file.
            // This needs to be the same even with multi-targeting. It's the
            // full name -- not the assembly qualified name.
            resMgrHeaderPart.Write(ResSetTypeName);
            resMgrHeaderPart.Flush();

            // Write number of bytes to skip over to get past ResMgr header
            bw.Write((int)resMgrHeaderBlob.Length);

            // Write the rest of the ResMgr header
            resMgrHeaderBlob.Seek(0, SeekOrigin.Begin);
            resMgrHeaderBlob.CopyTo(bw.BaseStream, (int)resMgrHeaderBlob.Length);
            // End ResourceManager header


            // Write out the RuntimeResourceSet header
            // Version number
            bw.Write(ResSetVersion);

            // number of resources
            int numResources = _resourceList.Count;

            bw.Write(numResources);

            // Store values in temporary streams to write at end of file.
            int[]        nameHashes    = new int[numResources];
            int[]        namePositions = new int[numResources];
            int          curNameNumber = 0;
            MemoryStream nameSection   = new MemoryStream(numResources * AverageNameSize);
            BinaryWriter names         = new BinaryWriter(nameSection, Encoding.Unicode);

            Stream dataSection = new MemoryStream();  // Either a FileStream or a MemoryStream

            using (dataSection)
            {
                BinaryWriter data = new BinaryWriter(dataSection, Encoding.UTF8);

                // We've stored our resources internally in a Hashtable, which
                // makes no guarantees about the ordering while enumerating.
                // While we do our own sorting of the resource names based on their
                // hash values, that's only sorting the nameHashes and namePositions
                // arrays.  That's all that is strictly required for correctness,
                // but for ease of generating a patch in the future that
                // modifies just .resources files, we should re-sort them.


                // Write resource name and position to the file, and the value
                // to our temporary buffer.  Save Type as well.
                foreach (var items in _resourceList)
                {
                    nameHashes[curNameNumber]      = FastResourceComparer.HashFunction((String)items.Key);
                    namePositions[curNameNumber++] = (int)names.Seek(0, SeekOrigin.Current);
                    names.Write((String)items.Key);                     // key
                    names.Write((int)data.Seek(0, SeekOrigin.Current)); // virtual offset of value.

                    String value = items.Value;

                    // Write out type code
                    Write7BitEncodedInt(data, ResourceTypeCodeString);

                    // Write out value
                    data.Write(value);
                }

                // At this point, the ResourceManager header has been written.
                // Finish RuntimeResourceSet header
                // The reader expects a list of user defined type names
                // following the size of the list, write 0 for this
                // writer implementation
                bw.Write((int)0);

                // Write out the name-related items for lookup.
                //  Note that the hash array and the namePositions array must
                //  be sorted in parallel.
                Array.Sort(nameHashes, namePositions);


                //  Prepare to write sorted name hashes (alignment fixup)
                //   Note: For 64-bit machines, these MUST be aligned on 8 byte
                //   boundaries!  Pointers on IA64 must be aligned!  And we'll
                //   run faster on X86 machines too.
                bw.Flush();
                int alignBytes = ((int)bw.BaseStream.Position) & 7;
                if (alignBytes > 0)
                {
                    for (int i = 0; i < 8 - alignBytes; i++)
                    {
                        bw.Write("PAD"[i % 3]);
                    }
                }

                //  Write out sorted name hashes.
                //   Align to 8 bytes.
                Debug.Assert((bw.BaseStream.Position & 7) == 0, "ResourceWriter: Name hashes array won't be 8 byte aligned!  Ack!");

                foreach (int hash in nameHashes)
                {
                    bw.Write(hash);
                }

                //  Write relative positions of all the names in the file.
                //   Note: this data is 4 byte aligned, occurring immediately
                //   after the 8 byte aligned name hashes (whose length may
                //   potentially be odd).
                Debug.Assert((bw.BaseStream.Position & 3) == 0, "ResourceWriter: Name positions array won't be 4 byte aligned!  Ack!");

                foreach (int pos in namePositions)
                {
                    bw.Write(pos);
                }

                // Flush all BinaryWriters to their underlying streams.
                bw.Flush();
                names.Flush();
                data.Flush();

                // Write offset to data section
                int startOfDataSection = (int)(bw.Seek(0, SeekOrigin.Current) + nameSection.Length);
                startOfDataSection += 4;  // We're writing an int to store this data, adding more bytes to the header
                bw.Write(startOfDataSection);

                // Write name section.
                nameSection.Seek(0, SeekOrigin.Begin);
                nameSection.CopyTo(bw.BaseStream, (int)nameSection.Length);
                names.Dispose();

                // Write data section.
                Debug.Assert(startOfDataSection == bw.Seek(0, SeekOrigin.Current), "ResourceWriter::Generate - start of data section is wrong!");
                dataSection.Position = 0;
                dataSection.CopyTo(bw.BaseStream);
                data.Dispose();
            } // using(dataSection)  <--- Closes dataSection, which was opened w/ FileOptions.DeleteOnClose
            bw.Flush();

            // Indicate we've called Generate
            _resourceList = null;
        }
Пример #7
0
 public int GetHashCode(string?key)  // TODO-NULLABLE: argument should be non-nullable but IEqualityComparer.Equals accepts null
 {
     Debug.Assert(key != null, "TODO-NULLABLE");
     return(FastResourceComparer.HashFunction(key));
 }
Пример #8
0
        public void Generate()
        {
            if (this._resourceList == null)
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceWriterSaved"));
            }
            BinaryWriter  binaryWriter1 = new BinaryWriter(this._output, Encoding.UTF8);
            List <string> types         = new List <string>();

            binaryWriter1.Write(ResourceManager.MagicNumber);
            binaryWriter1.Write(ResourceManager.HeaderVersionNumber);
            MemoryStream memoryStream1         = new MemoryStream(240);
            BinaryWriter binaryWriter2         = new BinaryWriter((Stream)memoryStream1);
            string       assemblyQualifiedName = MultitargetingHelpers.GetAssemblyQualifiedName(typeof(ResourceReader), this.typeConverter);

            binaryWriter2.Write(assemblyQualifiedName);
            string str = ResourceManager.ResSetTypeName;

            binaryWriter2.Write(str);
            binaryWriter2.Flush();
            binaryWriter1.Write((int)memoryStream1.Length);
            binaryWriter1.Write(memoryStream1.GetBuffer(), 0, (int)memoryStream1.Length);
            binaryWriter1.Write(2);
            int count = this._resourceList.Count;

            if (this._preserializedData != null)
            {
                count += this._preserializedData.Count;
            }
            binaryWriter1.Write(count);
            int[]         keys          = new int[count];
            int[]         items         = new int[count];
            int           index1        = 0;
            MemoryStream  memoryStream2 = new MemoryStream(count * 40);
            BinaryWriter  binaryWriter3 = new BinaryWriter((Stream)memoryStream2, Encoding.Unicode);
            Stream        output        = (Stream)null;
            PermissionSet permissionSet = new PermissionSet(PermissionState.None);

            permissionSet.AddPermission((IPermission) new EnvironmentPermission(PermissionState.Unrestricted));
            permissionSet.AddPermission((IPermission) new FileIOPermission(PermissionState.Unrestricted));
            try
            {
                permissionSet.Assert();
                string tempFileName = Path.GetTempFileName();
                int    num1         = 8448;
                File.SetAttributes(tempFileName, (FileAttributes)num1);
                int num2       = 3;
                int num3       = 3;
                int num4       = 1;
                int bufferSize = 4096;
                int num5       = 201326592;
                output = (Stream) new FileStream(tempFileName, (FileMode)num2, (FileAccess)num3, (FileShare)num4, bufferSize, (FileOptions)num5);
            }
            catch (UnauthorizedAccessException ex)
            {
                output = (Stream) new MemoryStream();
            }
            catch (IOException ex)
            {
                output = (Stream) new MemoryStream();
            }
            finally
            {
                PermissionSet.RevertAssert();
            }
            using (output)
            {
                BinaryWriter binaryWriter4 = new BinaryWriter(output, Encoding.UTF8);
                IFormatter   objFormatter  = (IFormatter) new BinaryFormatter((ISurrogateSelector)null, new StreamingContext(StreamingContextStates.File | StreamingContextStates.Persistence));
                SortedList   sortedList    = new SortedList((IDictionary)this._resourceList, (IComparer)FastResourceComparer.Default);
                if (this._preserializedData != null)
                {
                    foreach (KeyValuePair <string, ResourceWriter.PrecannedResource> keyValuePair in this._preserializedData)
                    {
                        sortedList.Add((object)keyValuePair.Key, (object)keyValuePair.Value);
                    }
                }
                IDictionaryEnumerator enumerator = sortedList.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    keys[index1]    = FastResourceComparer.HashFunction((string)enumerator.Key);
                    items[index1++] = (int)binaryWriter3.Seek(0, SeekOrigin.Current);
                    binaryWriter3.Write((string)enumerator.Key);
                    binaryWriter3.Write((int)binaryWriter4.Seek(0, SeekOrigin.Current));
                    object           obj      = enumerator.Value;
                    ResourceTypeCode typeCode = this.FindTypeCode(obj, types);
                    ResourceWriter.Write7BitEncodedInt(binaryWriter4, (int)typeCode);
                    ResourceWriter.PrecannedResource precannedResource = obj as ResourceWriter.PrecannedResource;
                    if (precannedResource != null)
                    {
                        binaryWriter4.Write(precannedResource.Data);
                    }
                    else
                    {
                        this.WriteValue(typeCode, obj, binaryWriter4, objFormatter);
                    }
                }
                binaryWriter1.Write(types.Count);
                for (int index2 = 0; index2 < types.Count; ++index2)
                {
                    binaryWriter1.Write(types[index2]);
                }
                Array.Sort <int, int>(keys, items);
                binaryWriter1.Flush();
                int num1 = (int)binaryWriter1.BaseStream.Position & 7;
                if (num1 > 0)
                {
                    for (int index2 = 0; index2 < 8 - num1; ++index2)
                    {
                        binaryWriter1.Write("PAD"[index2 % 3]);
                    }
                }
                foreach (int num2 in keys)
                {
                    binaryWriter1.Write(num2);
                }
                foreach (int num2 in items)
                {
                    binaryWriter1.Write(num2);
                }
                binaryWriter1.Flush();
                binaryWriter3.Flush();
                binaryWriter4.Flush();
                int num3 = (int)(binaryWriter1.Seek(0, SeekOrigin.Current) + memoryStream2.Length) + 4;
                binaryWriter1.Write(num3);
                binaryWriter1.Write(memoryStream2.GetBuffer(), 0, (int)memoryStream2.Length);
                binaryWriter3.Close();
                output.Position = 0L;
                output.CopyTo(binaryWriter1.BaseStream);
                binaryWriter4.Close();
            }
            binaryWriter1.Flush();
            this._resourceList = (Dictionary <string, object>)null;
        }
        public void Generate()
        {
            if (this._resourceList == null)
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceWriterSaved"));
            }
            BinaryWriter  binaryWriter = new BinaryWriter(this._output, Encoding.UTF8);
            List <string> list         = new List <string>();

            binaryWriter.Write(ResourceManager.MagicNumber);
            binaryWriter.Write(ResourceManager.HeaderVersionNumber);
            MemoryStream memoryStream  = new MemoryStream(240);
            BinaryWriter binaryWriter2 = new BinaryWriter(memoryStream);

            binaryWriter2.Write(MultitargetingHelpers.GetAssemblyQualifiedName(typeof(ResourceReader), this.typeConverter));
            binaryWriter2.Write(ResourceManager.ResSetTypeName);
            binaryWriter2.Flush();
            binaryWriter.Write((int)memoryStream.Length);
            binaryWriter.Write(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
            binaryWriter.Write(2);
            int num = this._resourceList.Count;

            if (this._preserializedData != null)
            {
                num += this._preserializedData.Count;
            }
            binaryWriter.Write(num);
            int[]         array         = new int[num];
            int[]         array2        = new int[num];
            int           num2          = 0;
            MemoryStream  memoryStream2 = new MemoryStream(num * 40);
            BinaryWriter  binaryWriter3 = new BinaryWriter(memoryStream2, Encoding.Unicode);
            Stream        stream        = null;
            PermissionSet permissionSet = new PermissionSet(PermissionState.None);

            permissionSet.AddPermission(new EnvironmentPermission(PermissionState.Unrestricted));
            permissionSet.AddPermission(new FileIOPermission(PermissionState.Unrestricted));
            try
            {
                permissionSet.Assert();
                string tempFileName = Path.GetTempFileName();
                File.SetAttributes(tempFileName, FileAttributes.Temporary | FileAttributes.NotContentIndexed);
                stream = new FileStream(tempFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, 4096, FileOptions.DeleteOnClose | FileOptions.SequentialScan);
            }
            catch (UnauthorizedAccessException)
            {
                stream = new MemoryStream();
            }
            catch (IOException)
            {
                stream = new MemoryStream();
            }
            finally
            {
                PermissionSet.RevertAssert();
            }
            using (stream)
            {
                BinaryWriter binaryWriter4 = new BinaryWriter(stream, Encoding.UTF8);
                IFormatter   objFormatter  = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File | StreamingContextStates.Persistence));
                SortedList   sortedList    = new SortedList(this._resourceList, FastResourceComparer.Default);
                if (this._preserializedData != null)
                {
                    foreach (KeyValuePair <string, ResourceWriter.PrecannedResource> keyValuePair in this._preserializedData)
                    {
                        sortedList.Add(keyValuePair.Key, keyValuePair.Value);
                    }
                }
                IDictionaryEnumerator enumerator2 = sortedList.GetEnumerator();
                while (enumerator2.MoveNext())
                {
                    array[num2]    = FastResourceComparer.HashFunction((string)enumerator2.Key);
                    array2[num2++] = (int)binaryWriter3.Seek(0, SeekOrigin.Current);
                    binaryWriter3.Write((string)enumerator2.Key);
                    binaryWriter3.Write((int)binaryWriter4.Seek(0, SeekOrigin.Current));
                    object           value            = enumerator2.Value;
                    ResourceTypeCode resourceTypeCode = this.FindTypeCode(value, list);
                    ResourceWriter.Write7BitEncodedInt(binaryWriter4, (int)resourceTypeCode);
                    ResourceWriter.PrecannedResource precannedResource = value as ResourceWriter.PrecannedResource;
                    if (precannedResource != null)
                    {
                        binaryWriter4.Write(precannedResource.Data);
                    }
                    else
                    {
                        this.WriteValue(resourceTypeCode, value, binaryWriter4, objFormatter);
                    }
                }
                binaryWriter.Write(list.Count);
                for (int i = 0; i < list.Count; i++)
                {
                    binaryWriter.Write(list[i]);
                }
                Array.Sort <int, int>(array, array2);
                binaryWriter.Flush();
                int num3 = (int)binaryWriter.BaseStream.Position & 7;
                if (num3 > 0)
                {
                    for (int j = 0; j < 8 - num3; j++)
                    {
                        binaryWriter.Write("PAD"[j % 3]);
                    }
                }
                foreach (int value2 in array)
                {
                    binaryWriter.Write(value2);
                }
                foreach (int value3 in array2)
                {
                    binaryWriter.Write(value3);
                }
                binaryWriter.Flush();
                binaryWriter3.Flush();
                binaryWriter4.Flush();
                int num4 = (int)(binaryWriter.Seek(0, SeekOrigin.Current) + memoryStream2.Length);
                num4 += 4;
                binaryWriter.Write(num4);
                binaryWriter.Write(memoryStream2.GetBuffer(), 0, (int)memoryStream2.Length);
                binaryWriter3.Close();
                stream.Position = 0L;
                stream.CopyTo(binaryWriter.BaseStream);
                binaryWriter4.Close();
            }
            binaryWriter.Flush();
            this._resourceList = null;
        }
Пример #10
0
        internal int FindPosForResource(string name)
        {
            int  num1  = FastResourceComparer.HashFunction(name);
            int  num2  = 0;
            int  num3  = this._numResources - 1;
            int  index = -1;
            bool flag  = false;

            while (num2 <= num3)
            {
                index = num2 + num3 >> 1;
                int nameHash = this.GetNameHash(index);
                int num4     = nameHash != num1 ? (nameHash >= num1 ? 1 : -1) : 0;
                if (num4 == 0)
                {
                    flag = true;
                    break;
                }
                if (num4 < 0)
                {
                    num2 = index + 1;
                }
                else
                {
                    num3 = index - 1;
                }
            }
            if (!flag)
            {
                return(-1);
            }
            if (num2 != index)
            {
                num2 = index;
                while (num2 > 0 && this.GetNameHash(num2 - 1) == num1)
                {
                    --num2;
                }
            }
            if (num3 != index)
            {
                num3 = index;
                while (num3 < this._numResources - 1 && this.GetNameHash(num3 + 1) == num1)
                {
                    ++num3;
                }
            }
            lock (this)
            {
                for (int local_9 = num2; local_9 <= num3; ++local_9)
                {
                    this._store.BaseStream.Seek(this._nameSectionOffset + (long)this.GetNamePosition(local_9), SeekOrigin.Begin);
                    if (this.CompareStringEqualsName(name))
                    {
                        int local_10 = this._store.ReadInt32();
                        if (local_10 < 0 || (long)local_10 >= this._store.BaseStream.Length - this._dataSectionOffset)
                        {
                            throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", (object)local_10));
                        }
                        return(local_10);
                    }
                }
            }
            return(-1);
        }
        internal int FindPosForResource(string name)
        {
            int  num   = FastResourceComparer.HashFunction(name);
            int  num2  = 0;
            int  num3  = this._numResources - 1;
            int  index = -1;
            bool flag  = false;

            while (num2 <= num3)
            {
                int num6;
                index = (num2 + num3) >> 1;
                int nameHash = this.GetNameHash(index);
                if (nameHash == num)
                {
                    num6 = 0;
                }
                else if (nameHash < num)
                {
                    num6 = -1;
                }
                else
                {
                    num6 = 1;
                }
                if (num6 == 0)
                {
                    flag = true;
                    break;
                }
                if (num6 < 0)
                {
                    num2 = index + 1;
                }
                else
                {
                    num3 = index - 1;
                }
            }
            if (flag)
            {
                if (num2 != index)
                {
                    num2 = index;
                    while ((num2 > 0) && (this.GetNameHash(num2 - 1) == num))
                    {
                        num2--;
                    }
                }
                if (num3 != index)
                {
                    num3 = index;
                    while ((num3 < (this._numResources - 1)) && (this.GetNameHash(num3 + 1) == num))
                    {
                        num3++;
                    }
                }
                lock (this)
                {
                    for (int i = num2; i <= num3; i++)
                    {
                        this._store.BaseStream.Seek(this._nameSectionOffset + this.GetNamePosition(i), SeekOrigin.Begin);
                        if (this.CompareStringEqualsName(name))
                        {
                            int num8 = this._store.ReadInt32();
                            if ((num8 < 0) || (num8 >= (this._store.BaseStream.Length - this._dataSectionOffset)))
                            {
                                throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", new object[] { num8 }));
                            }
                            return(num8);
                        }
                    }
                }
            }
            return(-1);
        }