diff options
Diffstat (limited to 'src/mscorlib/src/System/Resources/ResourceReader.cs')
-rw-r--r-- | src/mscorlib/src/System/Resources/ResourceReader.cs | 671 |
1 files changed, 392 insertions, 279 deletions
diff --git a/src/mscorlib/src/System/Resources/ResourceReader.cs b/src/mscorlib/src/System/Resources/ResourceReader.cs index d752771020..9734343f92 100644 --- a/src/mscorlib/src/System/Resources/ResourceReader.cs +++ b/src/mscorlib/src/System/Resources/ResourceReader.cs @@ -14,7 +14,9 @@ ** Version 2 support on October 6, 2003 ** ===========================================================*/ -namespace System.Resources { + +namespace System.Resources +{ using System; using System.IO; using System.Text; @@ -47,14 +49,16 @@ namespace System.Resources { _value = value; } - internal int DataPosition { + internal int DataPosition + { get { return _dataPos; } //set { _dataPos = value; } } // Allows adding in profiling data in a future version, or a special // resource profiling build. We could also use WeakReference. - internal Object Value { + internal Object Value + { get { return _value; } set { _value = value; } } @@ -63,7 +67,7 @@ namespace System.Resources { { Debug.Assert(value >= 0, "negative ResourceTypeCode. What?"); return value <= ResourceTypeCode.LastPrimitive; - } + } } @@ -111,23 +115,25 @@ namespace System.Resources { { _resCache = new Dictionary<String, ResourceLocator>(FastResourceComparer.Default); _store = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.RandomAccess), Encoding.UTF8); - BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(String). UnmanagedMemoryStream: "+(_ums!=null)); + BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(String). UnmanagedMemoryStream: " + (_ums != null)); - try { + try + { ReadResources(); } - catch { + catch + { _store.Close(); // If we threw an exception, close the file. throw; } } - + public ResourceReader(Stream stream) { - if (stream==null) + if (stream == null) throw new ArgumentNullException(nameof(stream)); if (!stream.CanRead) - throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable")); + throw new ArgumentException(SR.Argument_StreamNotReadable); Contract.EndContractBlock(); _resCache = new Dictionary<String, ResourceLocator>(FastResourceComparer.Default); @@ -135,10 +141,10 @@ namespace System.Resources { // We have a faster code path for reading resource files from an assembly. _ums = stream as UnmanagedMemoryStream; - BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(Stream). UnmanagedMemoryStream: "+(_ums!=null)); + BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(Stream). UnmanagedMemoryStream: " + (_ums != null)); ReadResources(); } - + // This is the constructor the RuntimeResourceSet calls, // passing in the stream to read from and the RuntimeResourceSet's // internal hash table (hash table of names with file offsets @@ -154,16 +160,16 @@ namespace System.Resources { _ums = stream as UnmanagedMemoryStream; - BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(Stream, Hashtable). UnmanagedMemoryStream: "+(_ums!=null)); + BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(Stream, Hashtable). UnmanagedMemoryStream: " + (_ums != null)); ReadResources(); } - + public void Close() { Dispose(true); } - + public void Dispose() { Close(); @@ -171,9 +177,11 @@ namespace System.Resources { private unsafe void Dispose(bool disposing) { - if (_store != null) { + if (_store != null) + { _resCache = null; - if (disposing) { + if (disposing) + { // Close the stream in a thread-safe way. This fix means // that we may call Close n times, but that's safe. BinaryReader copyOfStore = _store; @@ -189,27 +197,29 @@ namespace System.Resources { _nameHashesPtr = null; } } - + internal static unsafe int ReadUnalignedI4(int* p) { byte* buffer = (byte*)p; // Unaligned, little endian format return buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); } - - private void SkipString() { + + private void SkipString() + { int stringLength = _store.Read7BitEncodedInt(); - if (stringLength < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength")); + if (stringLength < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_NegativeStringLength); } _store.BaseStream.Seek(stringLength, SeekOrigin.Current); } private unsafe int GetNameHash(int index) { - Debug.Assert(index >=0 && index < _numResources, "Bad index into hash array. index: "+index); - Debug.Assert((_ums == null && _nameHashes != null && _nameHashesPtr == null) || + Debug.Assert(index >= 0 && index < _numResources, "Bad index into hash array. index: " + index); + Debug.Assert((_ums == null && _nameHashes != null && _nameHashesPtr == null) || (_ums != null && _nameHashes == null && _nameHashesPtr != null), "Internal state mangled."); if (_ums == null) return _nameHashes[index]; @@ -219,16 +229,17 @@ namespace System.Resources { private unsafe int GetNamePosition(int index) { - Debug.Assert(index >=0 && index < _numResources, "Bad index into name position array. index: "+index); - Debug.Assert((_ums == null && _namePositions != null && _namePositionsPtr == null) || + Debug.Assert(index >= 0 && index < _numResources, "Bad index into name position array. index: " + index); + Debug.Assert((_ums == null && _namePositions != null && _namePositionsPtr == null) || (_ums != null && _namePositions == null && _namePositionsPtr != null), "Internal state mangled."); int r; if (_ums == null) r = _namePositions[index]; else r = ReadUnalignedI4(&_namePositionsPtr[index]); - if (r < 0 || r > _dataSectionOffset - _nameSectionOffset) { - throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesNameInvalidOffset", r)); + if (r < 0 || r > _dataSectionOffset - _nameSectionOffset) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesNameInvalidOffset, r)); } return r; } @@ -241,7 +252,7 @@ namespace System.Resources { public IDictionaryEnumerator GetEnumerator() { if (_resCache == null) - throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed")); + throw new InvalidOperationException(SR.ResourceReaderIsClosed); return new ResourceEnumerator(this); } @@ -258,14 +269,15 @@ namespace System.Resources { { Debug.Assert(_store != null, "ResourceReader is closed!"); int hash = FastResourceComparer.HashFunction(name); - BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for "+name+" hash: "+hash.ToString("x", CultureInfo.InvariantCulture)); + BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for " + name + " hash: " + hash.ToString("x", CultureInfo.InvariantCulture)); // 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) { + while (lo <= hi) + { index = (lo + hi) >> 1; // Do NOT use subtraction here, since it will wrap for large // negative numbers. @@ -278,7 +290,8 @@ namespace System.Resources { else c = 1; //BCLDebug.Log("RESMGRFILEFORMAT", " Probing index "+index+" lo: "+lo+" hi: "+hi+" c: "+c); - if (c == 0) { + if (c == 0) + { success = true; break; } @@ -287,7 +300,8 @@ namespace System.Resources { else hi = index - 1; } - if (!success) { + if (!success) + { #if RESOURCE_FILE_FORMAT_DEBUG String lastReadString; lock(this) { @@ -298,36 +312,42 @@ namespace System.Resources { #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) { + if (lo != index) + { lo = index; while (lo > 0 && GetNameHash(lo - 1) == hash) lo--; } - if (hi != index) { + if (hi != index) + { hi = index; while (hi < _numResources - 1 && GetNameHash(hi + 1) == hash) hi++; } - lock(this) { - for(int i = lo; i<=hi; i++) { + lock (this) + { + for (int i = lo; i <= hi; i++) + { _store.BaseStream.Seek(_nameSectionOffset + GetNamePosition(i), SeekOrigin.Begin); - if (CompareStringEqualsName(name)) { + if (CompareStringEqualsName(name)) + { int dataPos = _store.ReadInt32(); - if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset) { - throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataPos)); + if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataPos)); } return dataPos; } } } - BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for "+name+": Found a hash collision, HOWEVER, neither of these collided values equaled the given string."); + BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for " + name + ": Found a hash collision, HOWEVER, neither of these collided values equaled the given string."); return -1; } @@ -339,15 +359,18 @@ namespace System.Resources { { Debug.Assert(_store != null, "ResourceReader is closed!"); int byteLen = _store.Read7BitEncodedInt(); - if (byteLen < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength")); + if (byteLen < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_NegativeStringLength); } - if (_ums != null) { + if (_ums != null) + { byte* bytes = _ums.PositionPointer; // Skip over the data in the Stream, positioning ourselves right after it. _ums.Seek(byteLen, SeekOrigin.Current); - if (_ums.Position > _ums.Length) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesNameTooLong")); + if (_ums.Position > _ums.Length) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesNameTooLong); } // On 64-bit machines, these char*'s may be misaligned. Use a @@ -355,17 +378,19 @@ namespace System.Resources { //return FastResourceComparer.CompareOrdinal((char*)bytes, byteLen/2, name) == 0; return FastResourceComparer.CompareOrdinal(bytes, byteLen, name) == 0; } - else { + else + { // This code needs to be fast byte[] bytes = new byte[byteLen]; int numBytesToRead = byteLen; - while(numBytesToRead > 0) { + while (numBytesToRead > 0) + { int n = _store.Read(bytes, byteLen - numBytesToRead, numBytesToRead); if (n == 0) - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceNameCorrupted")); + throw new BadImageFormatException(SR.BadImageFormat_ResourceNameCorrupted); numBytesToRead -= n; } - return FastResourceComparer.CompareOrdinal(bytes, byteLen/2, name) == 0; + return FastResourceComparer.CompareOrdinal(bytes, byteLen / 2, name) == 0; } } @@ -378,17 +403,20 @@ namespace System.Resources { byte[] bytes; int byteLen; long nameVA = GetNamePosition(index); - lock (this) { + lock (this) + { _store.BaseStream.Seek(nameVA + _nameSectionOffset, SeekOrigin.Begin); // Can't use _store.ReadString, since it's using UTF-8! byteLen = _store.Read7BitEncodedInt(); - if (byteLen < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength")); + if (byteLen < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_NegativeStringLength); } - if (_ums != null) { + if (_ums != null) + { if (_ums.Position > _ums.Length - byteLen) - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesIndexTooLong", index)); + throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourcesIndexTooLong, index)); String s = null; char* charPtr = (char*)_ums.PositionPointer; @@ -402,14 +430,15 @@ namespace System.Resources { } else { #endif //IA64 - s = new String(charPtr, 0, byteLen/2); + s = new String(charPtr, 0, byteLen / 2); #if IA64 } #endif //IA64 _ums.Position += byteLen; dataOffset = _store.ReadInt32(); - if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset) { - throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataOffset)); + if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataOffset)); } return s; } @@ -419,15 +448,17 @@ namespace System.Resources { // Use a blocking read in case the stream doesn't give us back // everything immediately. int count = byteLen; - while(count > 0) { + while (count > 0) + { int n = _store.Read(bytes, byteLen - count, count); if (n == 0) - throw new EndOfStreamException(Environment.GetResourceString("BadImageFormat_ResourceNameCorrupted_NameIndex", index)); + throw new EndOfStreamException(SR.Format(SR.BadImageFormat_ResourceNameCorrupted_NameIndex, index)); count -= n; } dataOffset = _store.ReadInt32(); - if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset) { - throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataOffset)); + if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataOffset)); } } return Encoding.Unicode.GetString(bytes, 0, byteLen); @@ -440,15 +471,17 @@ namespace System.Resources { { Debug.Assert(_store != null, "ResourceReader is closed!"); long nameVA = GetNamePosition(index); - lock(this) { + lock (this) + { _store.BaseStream.Seek(nameVA + _nameSectionOffset, SeekOrigin.Begin); SkipString(); //BCLDebug.Log("RESMGRFILEFORMAT", "GetValueForNameIndex for index: "+index+" skip (name length): "+skip); int dataPos = _store.ReadInt32(); - if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset) { - throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataPos)); + if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataPos)); } - BCLDebug.Log("RESMGRFILEFORMAT", "GetValueForNameIndex: dataPos: "+dataPos); + BCLDebug.Log("RESMGRFILEFORMAT", "GetValueForNameIndex: dataPos: " + dataPos); ResourceTypeCode junk; if (_version == 1) return LoadObjectV1(dataPos); @@ -464,30 +497,33 @@ namespace System.Resources { internal String LoadString(int pos) { Debug.Assert(_store != null, "ResourceReader is closed!"); - _store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin); + _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin); String s = null; int typeIndex = _store.Read7BitEncodedInt(); - if (_version == 1) { + if (_version == 1) + { if (typeIndex == -1) return null; if (FindType(typeIndex) != typeof(String)) - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Type", FindType(typeIndex).FullName)); + throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotString_Type, FindType(typeIndex).FullName)); s = _store.ReadString(); } - else { - ResourceTypeCode typeCode = (ResourceTypeCode) typeIndex; - if (typeCode != ResourceTypeCode.String && typeCode != ResourceTypeCode.Null) { + else + { + ResourceTypeCode typeCode = (ResourceTypeCode)typeIndex; + if (typeCode != ResourceTypeCode.String && typeCode != ResourceTypeCode.Null) + { String typeString; if (typeCode < ResourceTypeCode.StartOfUserTypes) typeString = typeCode.ToString(); else typeString = FindType(typeCode - ResourceTypeCode.StartOfUserTypes).FullName; - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Type", typeString)); + throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotString_Type, typeString)); } if (typeCode == ResourceTypeCode.String) // ignore Null s = _store.ReadString(); } - BCLDebug.Log("RESMGRFILEFORMAT", "LoadString("+pos.ToString("x", CultureInfo.InvariantCulture)+" returned "+(s==null ? "[a null string]" : s)); + BCLDebug.Log("RESMGRFILEFORMAT", "LoadString(" + pos.ToString("x", CultureInfo.InvariantCulture) + " returned " + (s == null ? "[a null string]" : s)); return s; } @@ -502,7 +538,8 @@ namespace System.Resources { internal Object LoadObject(int pos, out ResourceTypeCode typeCode) { - if (_version == 1) { + if (_version == 1) + { Object o = LoadObjectV1(pos); typeCode = (o is String) ? ResourceTypeCode.String : ResourceTypeCode.StartOfUserTypes; return o; @@ -519,26 +556,30 @@ namespace System.Resources { Debug.Assert(_store != null, "ResourceReader is closed!"); Debug.Assert(_version == 1, ".resources file was not a V1 .resources file!"); - try { + try + { // mega try-catch performs exceptionally bad on x64; factored out body into // _LoadObjectV1 and wrap here. return _LoadObjectV1(pos); } - catch (EndOfStreamException eof) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), eof); + catch (EndOfStreamException eof) + { + throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, eof); } - catch (ArgumentOutOfRangeException e) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), e); + catch (ArgumentOutOfRangeException e) + { + throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, e); } } - private Object _LoadObjectV1(int pos) { - _store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin); + private Object _LoadObjectV1(int pos) + { + _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin); int typeIndex = _store.Read7BitEncodedInt(); if (typeIndex == -1) return null; RuntimeType type = FindType(typeIndex); - BCLDebug.Log("RESMGRFILEFORMAT", "LoadObject type: "+type.Name+" pos: 0x"+_store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture)); + BCLDebug.Log("RESMGRFILEFORMAT", "LoadObject type: " + type.Name + " pos: 0x" + _store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture)); // Consider putting in logic to see if this type is a // primitive or a value type first, so we can reach the // deserialization code faster for arbitrary objects. @@ -565,21 +606,24 @@ namespace System.Resources { return _store.ReadSingle(); else if (type == typeof(Double)) return _store.ReadDouble(); - else if (type == typeof(DateTime)) { + else if (type == typeof(DateTime)) + { // Ideally we should use DateTime's ToBinary & FromBinary, // but we can't for compatibility reasons. return new DateTime(_store.ReadInt64()); } else if (type == typeof(TimeSpan)) return new TimeSpan(_store.ReadInt64()); - else if (type == typeof(Decimal)) { + else if (type == typeof(Decimal)) + { int[] bits = new int[4]; - for(int i=0; i<bits.Length; i++) + for (int i = 0; i < bits.Length; i++) bits[i] = _store.ReadInt32(); return new Decimal(bits); } - else { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_ResourceObjectSerialization")); + else + { + throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization); } } @@ -588,136 +632,152 @@ namespace System.Resources { Debug.Assert(_store != null, "ResourceReader is closed!"); Debug.Assert(_version >= 2, ".resources file was not a V2 (or higher) .resources file!"); - try { + try + { // mega try-catch performs exceptionally bad on x64; factored out body into // _LoadObjectV2 and wrap here. return _LoadObjectV2(pos, out typeCode); } - catch (EndOfStreamException eof) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), eof); + catch (EndOfStreamException eof) + { + throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, eof); } - catch (ArgumentOutOfRangeException e) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), e); + catch (ArgumentOutOfRangeException e) + { + throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, e); } } - private Object _LoadObjectV2(int pos, out ResourceTypeCode typeCode) { - _store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin); - typeCode = (ResourceTypeCode) _store.Read7BitEncodedInt(); + private Object _LoadObjectV2(int pos, out ResourceTypeCode typeCode) + { + _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin); + typeCode = (ResourceTypeCode)_store.Read7BitEncodedInt(); - BCLDebug.Log("RESMGRFILEFORMAT", "LoadObjectV2 type: "+typeCode+" pos: 0x"+_store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture)); - - switch(typeCode) { - case ResourceTypeCode.Null: - return null; + BCLDebug.Log("RESMGRFILEFORMAT", "LoadObjectV2 type: " + typeCode + " pos: 0x" + _store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture)); - case ResourceTypeCode.String: - return _store.ReadString(); - - case ResourceTypeCode.Boolean: - return _store.ReadBoolean(); + switch (typeCode) + { + case ResourceTypeCode.Null: + return null; - case ResourceTypeCode.Char: - return (char) _store.ReadUInt16(); + case ResourceTypeCode.String: + return _store.ReadString(); - case ResourceTypeCode.Byte: - return _store.ReadByte(); + case ResourceTypeCode.Boolean: + return _store.ReadBoolean(); - case ResourceTypeCode.SByte: - return _store.ReadSByte(); + case ResourceTypeCode.Char: + return (char)_store.ReadUInt16(); - case ResourceTypeCode.Int16: - return _store.ReadInt16(); + case ResourceTypeCode.Byte: + return _store.ReadByte(); - case ResourceTypeCode.UInt16: - return _store.ReadUInt16(); + case ResourceTypeCode.SByte: + return _store.ReadSByte(); - case ResourceTypeCode.Int32: - return _store.ReadInt32(); + case ResourceTypeCode.Int16: + return _store.ReadInt16(); - case ResourceTypeCode.UInt32: - return _store.ReadUInt32(); + case ResourceTypeCode.UInt16: + return _store.ReadUInt16(); - case ResourceTypeCode.Int64: - return _store.ReadInt64(); + case ResourceTypeCode.Int32: + return _store.ReadInt32(); - case ResourceTypeCode.UInt64: - return _store.ReadUInt64(); + case ResourceTypeCode.UInt32: + return _store.ReadUInt32(); - case ResourceTypeCode.Single: - return _store.ReadSingle(); + case ResourceTypeCode.Int64: + return _store.ReadInt64(); - case ResourceTypeCode.Double: - return _store.ReadDouble(); + case ResourceTypeCode.UInt64: + return _store.ReadUInt64(); - case ResourceTypeCode.Decimal: - return _store.ReadDecimal(); - - case ResourceTypeCode.DateTime: - // Use DateTime's ToBinary & FromBinary. - Int64 data = _store.ReadInt64(); - return DateTime.FromBinary(data); - - case ResourceTypeCode.TimeSpan: - Int64 ticks = _store.ReadInt64(); - return new TimeSpan(ticks); - - // Special types - case ResourceTypeCode.ByteArray: { - int len = _store.ReadInt32(); - if (len < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len)); - } + case ResourceTypeCode.Single: + return _store.ReadSingle(); + + case ResourceTypeCode.Double: + return _store.ReadDouble(); + + case ResourceTypeCode.Decimal: + return _store.ReadDecimal(); - if (_ums == null) { - if (len > _store.BaseStream.Length) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len)); + case ResourceTypeCode.DateTime: + // Use DateTime's ToBinary & FromBinary. + Int64 data = _store.ReadInt64(); + return DateTime.FromBinary(data); + + case ResourceTypeCode.TimeSpan: + Int64 ticks = _store.ReadInt64(); + return new TimeSpan(ticks); + + // Special types + case ResourceTypeCode.ByteArray: + { + int len = _store.ReadInt32(); + if (len < 0) + { + throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len)); } - return _store.ReadBytes(len); - } - if (len > _ums.Length - _ums.Position) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len)); - } + if (_ums == null) + { + if (len > _store.BaseStream.Length) + { + throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len)); + } + return _store.ReadBytes(len); + } - byte[] bytes = new byte[len]; - int r = _ums.Read(bytes, 0, len); - Debug.Assert(r == len, "ResourceReader needs to use a blocking read here. (Call _store.ReadBytes(len)?)"); - return bytes; - } + if (len > _ums.Length - _ums.Position) + { + throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len)); + } - case ResourceTypeCode.Stream: { - int len = _store.ReadInt32(); - if (len < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len)); - } - if (_ums == null) { - byte[] bytes = _store.ReadBytes(len); - // Lifetime of memory == lifetime of this stream. - return new PinnedBufferMemoryStream(bytes); + byte[] bytes = new byte[len]; + int r = _ums.Read(bytes, 0, len); + Debug.Assert(r == len, "ResourceReader needs to use a blocking read here. (Call _store.ReadBytes(len)?)"); + return bytes; } - // make sure we don't create an UnmanagedMemoryStream that is longer than the resource stream. - if (len > _ums.Length - _ums.Position) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len)); + case ResourceTypeCode.Stream: + { + int len = _store.ReadInt32(); + if (len < 0) + { + throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len)); + } + if (_ums == null) + { + byte[] bytes = _store.ReadBytes(len); + // Lifetime of memory == lifetime of this stream. + return new PinnedBufferMemoryStream(bytes); + } + + // make sure we don't create an UnmanagedMemoryStream that is longer than the resource stream. + if (len > _ums.Length - _ums.Position) + { + throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len)); + } + + // For the case that we've memory mapped in the .resources + // file, just return a Stream pointing to that block of memory. + unsafe + { + return new UnmanagedMemoryStream(_ums.PositionPointer, len, len, FileAccess.Read); + } } - // For the case that we've memory mapped in the .resources - // file, just return a Stream pointing to that block of memory. - unsafe { - return new UnmanagedMemoryStream(_ums.PositionPointer, len, len, FileAccess.Read); + default: + if (typeCode < ResourceTypeCode.StartOfUserTypes) + { + throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch); } - } - - default: - if (typeCode < ResourceTypeCode.StartOfUserTypes) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch")); - } - break; + break; } // Normal serialized objects - throw new NotSupportedException(Environment.GetResourceString("NotSupported_ResourceObjectSerialization")); + throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization); } @@ -729,16 +789,19 @@ namespace System.Resources { { Debug.Assert(_store != null, "ResourceReader is closed!"); - try { + try + { // mega try-catch performs exceptionally bad on x64; factored out body into // _ReadResources and wrap here. _ReadResources(); } - catch (EndOfStreamException eof) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"), eof); + catch (EndOfStreamException eof) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted, eof); } - catch (IndexOutOfRangeException e) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"), e); + catch (IndexOutOfRangeException e) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted, e); } } @@ -748,21 +811,24 @@ namespace System.Resources { // Check for magic number int magicNum = _store.ReadInt32(); if (magicNum != ResourceManager.MagicNumber) - throw new ArgumentException(Environment.GetResourceString("Resources_StreamNotValid")); + throw new ArgumentException(SR.Resources_StreamNotValid); // Assuming this is ResourceManager header V1 or greater, hopefully // after the version number there is a number of bytes to skip // to bypass the rest of the ResMgr header. For V2 or greater, we // use this to skip to the end of the header int resMgrHeaderVersion = _store.ReadInt32(); int numBytesToSkip = _store.ReadInt32(); - if (numBytesToSkip < 0 || resMgrHeaderVersion < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (numBytesToSkip < 0 || resMgrHeaderVersion < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } - if (resMgrHeaderVersion > 1) { + if (resMgrHeaderVersion > 1) + { BCLDebug.Log("RESMGRFILEFORMAT", LogLevel.Status, "ReadResources: Unexpected ResMgr header version: {0} Skipping ahead {1} bytes.", resMgrHeaderVersion, numBytesToSkip); _store.BaseStream.Seek(numBytesToSkip, SeekOrigin.Current); } - else { + else + { BCLDebug.Log("RESMGRFILEFORMAT", "ReadResources: Parsing ResMgr header v1."); // We don't care about numBytesToSkip; read the rest of the header @@ -773,7 +839,7 @@ namespace System.Resources { AssemblyName mscorlib = new AssemblyName(ResourceManager.MscorlibName); if (!ResourceManager.CompareNames(readerType, ResourceManager.ResReaderTypeName, mscorlib)) - throw new NotSupportedException(Environment.GetResourceString("NotSupported_WrongResourceReader_Type", readerType)); + throw new NotSupportedException(SR.Format(SR.NotSupported_WrongResourceReader_Type, readerType)); // Skip over type name for a suitable ResourceSet SkipString(); @@ -783,7 +849,7 @@ namespace System.Resources { // Do file version check int version = _store.ReadInt32(); if (version != RuntimeResourceSet.Version && version != 1) - throw new ArgumentException(Environment.GetResourceString("Arg_ResourceFileUnsupportedVersion", RuntimeResourceSet.Version, version)); + throw new ArgumentException(SR.Format(SR.Arg_ResourceFileUnsupportedVersion, RuntimeResourceSet.Version, version)); _version = version; #if RESOURCE_FILE_FORMAT_DEBUG @@ -807,8 +873,9 @@ namespace System.Resources { #endif _numResources = _store.ReadInt32(); - if (_numResources < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (_numResources < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } BCLDebug.Log("RESMGRFILEFORMAT", "ReadResources: Expecting " + _numResources + " resources."); #if RESOURCE_FILE_FORMAT_DEBUG @@ -819,13 +886,15 @@ namespace System.Resources { // Read type positions into type positions array. // But delay initialize the type table. int numTypes = _store.ReadInt32(); - if (numTypes < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (numTypes < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } _typeTable = new RuntimeType[numTypes]; _typeNamePositions = new int[numTypes]; - for (int i=0; i<numTypes; i++) { - _typeNamePositions[i] = (int) _store.BaseStream.Position; + for (int i = 0; i < numTypes; i++) + { + _typeNamePositions[i] = (int)_store.BaseStream.Position; // Skip over the Strings in the file. Don't create types. SkipString(); @@ -844,8 +913,10 @@ namespace System.Resources { // should be aligned No need to verify the byte values. long pos = _store.BaseStream.Position; int alignBytes = ((int)pos) & 7; - if (alignBytes != 0) { - for (int i = 0; i < 8 - alignBytes; i++) { + if (alignBytes != 0) + { + for (int i = 0; i < 8 - alignBytes; i++) + { _store.ReadByte(); } } @@ -858,18 +929,23 @@ namespace System.Resources { } #endif - if (_ums == null) { + if (_ums == null) + { _nameHashes = new int[_numResources]; - for (int i = 0; i < _numResources; i++) { + for (int i = 0; i < _numResources; i++) + { _nameHashes[i] = _store.ReadInt32(); } } - else { + else + { int seekPos = unchecked(4 * _numResources); - if (seekPos < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (seekPos < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } - unsafe { + unsafe + { _nameHashesPtr = (int*)_ums.PositionPointer; // Skip over the array of nameHashes. _ums.Seek(seekPos, SeekOrigin.Current); @@ -885,23 +961,29 @@ namespace System.Resources { _store.BaseStream.Position += 8; } #endif - if (_ums == null) { + if (_ums == null) + { _namePositions = new int[_numResources]; - for (int i = 0; i < _numResources; i++) { + for (int i = 0; i < _numResources; i++) + { int namePosition = _store.ReadInt32(); - if (namePosition < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (namePosition < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } _namePositions[i] = namePosition; } } - else { + else + { int seekPos = unchecked(4 * _numResources); - if (seekPos < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (seekPos < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } - unsafe { + unsafe + { _namePositionsPtr = (int*)_ums.PositionPointer; // Skip over the array of namePositions. _ums.Seek(seekPos, SeekOrigin.Current); @@ -912,16 +994,18 @@ namespace System.Resources { // Read location of data section. _dataSectionOffset = _store.ReadInt32(); - if (_dataSectionOffset < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (_dataSectionOffset < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } // Store current location as start of name section _nameSectionOffset = _store.BaseStream.Position; // _nameSectionOffset should be <= _dataSectionOffset; if not, it's corrupt - if (_dataSectionOffset < _nameSectionOffset) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (_dataSectionOffset < _nameSectionOffset) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } BCLDebug.Log("RESMGRFILEFORMAT", String.Format(CultureInfo.InvariantCulture, "ReadResources: _nameOffset = 0x{0:x} _dataOffset = 0x{1:x}", _nameSectionOffset, _dataSectionOffset)); @@ -932,12 +1016,15 @@ namespace System.Resources { // and initialize Reflection. private RuntimeType FindType(int typeIndex) { - if (typeIndex < 0 || typeIndex >= _typeTable.Length) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_InvalidType")); + if (typeIndex < 0 || typeIndex >= _typeTable.Length) + { + throw new BadImageFormatException(SR.BadImageFormat_InvalidType); } - if (_typeTable[typeIndex] == null) { + if (_typeTable[typeIndex] == null) + { long oldPos = _store.BaseStream.Position; - try { + try + { _store.BaseStream.Position = _typeNamePositions[typeIndex]; String typeName = _store.ReadString(); _typeTable[typeIndex] = (RuntimeType)Type.GetType(typeName, true); @@ -954,9 +1041,10 @@ namespace System.Resources { // getting to Type.GetType -- this is costly with v1 resource formats. catch (FileNotFoundException) { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_ResourceObjectSerialization")); + throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization); } - finally { + finally + { _store.BaseStream.Position = oldPos; } } @@ -971,7 +1059,7 @@ namespace System.Resources { throw new ArgumentNullException(nameof(resourceName)); Contract.EndContractBlock(); if (_resCache == null) - throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed")); + throw new InvalidOperationException(SR.ResourceReaderIsClosed); // Get the type information from the data section. Also, // sort all of the data section's indexes to compute length of @@ -979,24 +1067,29 @@ namespace System.Resources { // off the length of the type code). int[] sortedDataPositions = new int[_numResources]; int dataPos = FindPosForResource(resourceName); - if( dataPos == -1) { - throw new ArgumentException(Environment.GetResourceString("Arg_ResourceNameNotExist", resourceName)); + if (dataPos == -1) + { + throw new ArgumentException(SR.Format(SR.Arg_ResourceNameNotExist, resourceName)); } - - lock(this) { + + lock (this) + { // Read all the positions of data within the data section. - for(int i=0; i<_numResources; i++) { + for (int i = 0; i < _numResources; i++) + { _store.BaseStream.Position = _nameSectionOffset + GetNamePosition(i); // Skip over name of resource int numBytesToSkip = _store.Read7BitEncodedInt(); - if (numBytesToSkip < 0) { - throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesNameInvalidOffset", numBytesToSkip)); + if (numBytesToSkip < 0) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesNameInvalidOffset, numBytesToSkip)); } _store.BaseStream.Position += numBytesToSkip; int dPos = _store.ReadInt32(); - if (dPos < 0 || dPos >= _store.BaseStream.Length - _dataSectionOffset) { - throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dPos)); + if (dPos < 0 || dPos >= _store.BaseStream.Length - _dataSectionOffset) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dPos)); } sortedDataPositions[i] = dPos; } @@ -1005,23 +1098,24 @@ namespace System.Resources { int index = Array.BinarySearch(sortedDataPositions, dataPos); Debug.Assert(index >= 0 && index < _numResources, "Couldn't find data position within sorted data positions array!"); long nextData = (index < _numResources - 1) ? sortedDataPositions[index + 1] + _dataSectionOffset : _store.BaseStream.Length; - int len = (int) (nextData - (dataPos + _dataSectionOffset)); - Debug.Assert(len >= 0 && len <= (int) _store.BaseStream.Length - dataPos + _dataSectionOffset, "Length was negative or outside the bounds of the file!"); + int len = (int)(nextData - (dataPos + _dataSectionOffset)); + Debug.Assert(len >= 0 && len <= (int)_store.BaseStream.Length - dataPos + _dataSectionOffset, "Length was negative or outside the bounds of the file!"); // Read type code then byte[] _store.BaseStream.Position = _dataSectionOffset + dataPos; - ResourceTypeCode typeCode = (ResourceTypeCode) _store.Read7BitEncodedInt(); - if (typeCode < 0 || typeCode >= ResourceTypeCode.StartOfUserTypes + _typeTable.Length) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_InvalidType")); + ResourceTypeCode typeCode = (ResourceTypeCode)_store.Read7BitEncodedInt(); + if (typeCode < 0 || typeCode >= ResourceTypeCode.StartOfUserTypes + _typeTable.Length) + { + throw new BadImageFormatException(SR.BadImageFormat_InvalidType); } resourceType = TypeNameFromTypeCode(typeCode); // The length must be adjusted to subtract off the number // of bytes in the 7 bit encoded type code. - len -= (int) (_store.BaseStream.Position - (_dataSectionOffset + dataPos)); + len -= (int)(_store.BaseStream.Position - (_dataSectionOffset + dataPos)); byte[] bytes = _store.ReadBytes(len); if (bytes.Length != len) - throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourceNameCorrupted")); + throw new FormatException(SR.BadImageFormat_ResourceNameCorrupted); resourceData = bytes; } } @@ -1029,19 +1123,23 @@ namespace System.Resources { private String TypeNameFromTypeCode(ResourceTypeCode typeCode) { Contract.Requires(typeCode >= 0, "can't be negative"); - if (typeCode < ResourceTypeCode.StartOfUserTypes) { + if (typeCode < ResourceTypeCode.StartOfUserTypes) + { Debug.Assert(!String.Equals(typeCode.ToString(), "LastPrimitive"), "Change ResourceTypeCode metadata order so LastPrimitive isn't what Enum.ToString prefers."); return "ResourceTypeCode." + typeCode.ToString(); } - else { + else + { int typeIndex = typeCode - ResourceTypeCode.StartOfUserTypes; Debug.Assert(typeIndex >= 0 && typeIndex < _typeTable.Length, "TypeCode is broken or corrupted!"); long oldPos = _store.BaseStream.Position; - try { + try + { _store.BaseStream.Position = _typeNamePositions[typeIndex]; return _store.ReadString(); } - finally { + finally + { _store.BaseStream.Position = oldPos; } } @@ -1068,7 +1166,8 @@ namespace System.Resources { public bool MoveNext() { - if (_currentName == _reader._numResources - 1 || _currentName == ENUM_DONE) { + if (_currentName == _reader._numResources - 1 || _currentName == ENUM_DONE) + { _currentIsValid = false; _currentName = ENUM_DONE; return false; @@ -1077,49 +1176,61 @@ namespace System.Resources { _currentName++; return true; } - - public Object Key { - get { - if (_currentName == ENUM_DONE) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded)); - if (!_currentIsValid) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); - if (_reader._resCache == null) throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed")); + + public Object Key + { + get + { + if (_currentName == ENUM_DONE) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumEnded)); + if (!_currentIsValid) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); + if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed); return _reader.AllocateStringForNameIndex(_currentName, out _dataPosition); } } - - public Object Current { - get { + + public Object Current + { + get + { return Entry; } } // Warning: This requires that you call the Key or Entry property FIRST before calling it! - internal int DataPosition { - get { + internal int DataPosition + { + get + { return _dataPosition; } } - public DictionaryEntry Entry { - get { - if (_currentName == ENUM_DONE) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded)); - if (!_currentIsValid) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); - if (_reader._resCache == null) throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed")); + public DictionaryEntry Entry + { + get + { + if (_currentName == ENUM_DONE) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumEnded)); + if (!_currentIsValid) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); + if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed); String key; Object value = null; - lock (_reader) { // locks should be taken in the same order as in RuntimeResourceSet.GetObject to avoid deadlock - lock (_reader._resCache) { + lock (_reader) + { // locks should be taken in the same order as in RuntimeResourceSet.GetObject to avoid deadlock + lock (_reader._resCache) + { key = _reader.AllocateStringForNameIndex(_currentName, out _dataPosition); // AllocateStringForNameIndex could lock on _reader ResourceLocator locator; - if (_reader._resCache.TryGetValue(key, out locator)) { + if (_reader._resCache.TryGetValue(key, out locator)) + { value = locator.Value; } - if (value == null) { - if (_dataPosition == -1) + if (value == null) + { + if (_dataPosition == -1) value = _reader.GetValueForNameIndex(_currentName); - else + else value = _reader.LoadObject(_dataPosition); // If enumeration and subsequent lookups happen very // frequently in the same process, add a ResourceLocator @@ -1132,12 +1243,14 @@ namespace System.Resources { return new DictionaryEntry(key, value); } } - - public Object Value { - get { - if (_currentName == ENUM_DONE) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded)); - if (!_currentIsValid) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); - if (_reader._resCache == null) throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed")); + + public Object Value + { + get + { + if (_currentName == ENUM_DONE) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumEnded)); + if (!_currentIsValid) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); + if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed); // Consider using _resCache here, eventually, if // this proves to be an interesting perf scenario. @@ -1149,7 +1262,7 @@ namespace System.Resources { public void Reset() { - if (_reader._resCache == null) throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed")); + if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed); _currentIsValid = false; _currentName = ENUM_NOT_STARTED; } |