Jelajahi Sumber

2005-07-25 Marek Safar <[email protected]>

	*  ResourceReader.cs: Implemented reading of primitives for version 2.

svn path=/trunk/mcs/; revision=47640
Marek Safar 20 tahun lalu
induk
melakukan
eb747338c8

+ 4 - 0
mcs/class/corlib/System.Resources/ChangeLog

@@ -1,3 +1,7 @@
+2005-07-25  Marek Safar  <[email protected]>
+
+	*  ResourceReader.cs: Implemented reading of primitives for version 2.
+
 2005-03-31  Sebastien Pouliot  <[email protected]>
 
 	*  ResourceReader.cs, ResourceSet.cs: Added a LinkDemand for 

+ 167 - 70
mcs/class/corlib/System.Resources/ResourceReader.cs

@@ -5,6 +5,7 @@
 // 	Duncan Mak <[email protected]>
 //	Nick Drochak <[email protected]>
 //	Dick Porter <[email protected]>
+//	Marek Safar <[email protected]>
 //
 // (C) 2001, 2002 Ximian Inc, http://www.ximian.com
 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
@@ -39,6 +40,30 @@ using System.Security.Permissions;
 
 namespace System.Resources
 {
+	internal enum PredefinedResourceType
+	{
+		Null		= 0,
+		String		= 1,
+		Bool		= 2,
+		Char		= 3,
+		Byte		= 4,
+		SByte		= 5,
+		Int16		= 6,
+		UInt16		= 7,
+		Int32		= 8,
+		UInt32		= 9,
+		Int64		= 10,
+		UInt64		= 11,
+		Single		= 12,
+		Double		= 13,
+		Decimal		= 14,
+		DateTime	= 15,
+		TimeSpan	= 16,
+		ByteArray	= 32,
+		Stream		= 33,
+		FistCustom	= 64
+	}
+
 	public sealed class ResourceReader : IResourceReader, IEnumerable, IDisposable
 	{
 		BinaryReader reader;
@@ -50,6 +75,7 @@ namespace System.Resources
 		long[] positions;
 		int dataSectionOffset;
 		long nameSectionOffset;
+		int resource_ver;
 		
 		// Constructors
 		[SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
@@ -114,27 +140,23 @@ namespace System.Resources
 				}
 
 				/* Now read the ResourceReader header */
-				int reader_ver = reader.ReadInt32();
+				resource_ver = reader.ReadInt32();
 
-				if(reader_ver != 1) {
-					throw new NotSupportedException("This .resources file requires unsupported set class version: " + reader_ver.ToString());
+				if(resource_ver != 1
+#if NET_2_0
+					&& resource_ver != 2
+#endif
+					) {
+					throw new NotSupportedException("This .resources file requires unsupported set class version: " + resource_ver.ToString());
 				}
 
 				resourceCount = reader.ReadInt32();
 				typeCount = reader.ReadInt32();
 				
 				types=new Type[typeCount];
-				for(int i=0; i<typeCount; i++) {
-					string type_name=reader.ReadString();
 
-					/* FIXME: Should we ask for
-					 * type loading exceptions
-					 * here?
-					 */
-					types[i]=Type.GetType(type_name);
-					if(types[i]==null) {
-						throw new ArgumentException("Could not load type {0}", type_name);
-					}
+				for(int i=0; i<typeCount; i++) {
+					types[i]=Type.GetType(reader.ReadString(), true);
 				}
 
 				/* There are between 0 and 7 bytes of
@@ -222,6 +244,131 @@ namespace System.Resources
 			}
 		}
 
+		// TODO: Read complex types
+		object ReadValueVer2 (int type_index)
+		{
+			switch ((PredefinedResourceType)type_index)
+			{
+				case PredefinedResourceType.Null:
+					return null;
+
+				case PredefinedResourceType.String:
+					return reader.ReadString();
+
+				case PredefinedResourceType.Bool:
+					return reader.ReadBoolean ();
+
+				case PredefinedResourceType.Char:
+					return (char)reader.ReadUInt16();
+
+				case PredefinedResourceType.Byte:
+					return reader.ReadByte();
+
+				case PredefinedResourceType.SByte:
+					return reader.ReadSByte();
+
+				case PredefinedResourceType.Int16:
+					return reader.ReadInt16();
+
+				case PredefinedResourceType.UInt16:
+					return reader.ReadUInt16();
+
+				case PredefinedResourceType.Int32:
+					return reader.ReadInt32();
+
+				case PredefinedResourceType.UInt32:
+					return reader.ReadUInt32();
+
+				case PredefinedResourceType.Int64:
+					return reader.ReadInt64();
+
+				case PredefinedResourceType.UInt64:
+					return reader.ReadUInt64();
+
+				case PredefinedResourceType.Single:
+					return reader.ReadSingle();
+
+				case PredefinedResourceType.Double:
+					return reader.ReadDouble();
+
+				case PredefinedResourceType.Decimal:
+					return reader.ReadDecimal();
+
+				case PredefinedResourceType.DateTime:
+					return new DateTime(reader.ReadInt64());
+
+				case PredefinedResourceType.TimeSpan:
+					return new TimeSpan(reader.ReadInt64());
+
+				case PredefinedResourceType.ByteArray:
+					throw new NotImplementedException (PredefinedResourceType.ByteArray.ToString ());
+
+				case PredefinedResourceType.Stream:
+					throw new NotImplementedException (PredefinedResourceType.Stream.ToString ());
+			}
+
+			type_index -= (int)PredefinedResourceType.FistCustom;
+			return ReadNonPredefinedValue (types[type_index]);
+		}
+
+		object ReadValueVer1 (Type type)
+		{
+			// The most common first
+			if (type==typeof(String))
+				return reader.ReadString();
+			if (type==typeof(Int32))
+				return reader.ReadInt32();
+			if (type==typeof(Byte))
+				return(reader.ReadByte());
+			if (type==typeof(Double))
+				return(reader.ReadDouble());
+			if (type==typeof(Int16))
+				return(reader.ReadInt16());
+			if (type==typeof(Int64))
+				return(reader.ReadInt64());
+			if (type==typeof(SByte))
+				return(reader.ReadSByte());
+			if (type==typeof(Single))
+				return(reader.ReadSingle());
+			if (type==typeof(TimeSpan))
+				return(new TimeSpan(reader.ReadInt64()));
+			if (type==typeof(UInt16))
+				return(reader.ReadUInt16());
+			if (type==typeof(UInt32))
+				return(reader.ReadUInt32());
+			if (type==typeof(UInt64))
+				return(reader.ReadUInt64());
+			if (type==typeof(Decimal))
+				return(reader.ReadDecimal());
+			if (type==typeof(DateTime))
+				return(new DateTime(reader.ReadInt64()));
+
+			return ReadNonPredefinedValue(type);
+		}
+
+		// TODO: Add security checks
+		object ReadNonPredefinedValue (Type exp_type)
+		{
+			object obj=formatter.Deserialize(reader.BaseStream);
+			if(obj.GetType() != exp_type) {
+				/* We got a bogus
+						 * object.  This
+						 * exception is the
+						 * best match I could
+						 * find.  (.net seems
+						 * to throw
+						 * BadImageFormatException,
+						 * which the docs
+						 * state is used when
+						 * file or dll images
+						 * cant be loaded by
+						 * the runtime.)
+						 */
+				throw new InvalidOperationException("Deserialized object is wrong type");
+			}
+			return obj;
+		}
+
 		private object ResourceValue(int index)
 		{
 			lock(this)
@@ -240,65 +387,15 @@ namespace System.Resources
 				long data_offset=reader.ReadInt32();
 				reader.BaseStream.Seek(data_offset+dataSectionOffset, SeekOrigin.Begin);
 				int type_index=Read7BitEncodedInt();
+
+#if NET_2_0
+				if (resource_ver == 2)
+					return ReadValueVer2 (type_index);
+#endif
 				if (type_index == -1)
 					return null;
-				Type type=types[type_index];
-				
-				if (type==typeof(Byte)) {
-					return(reader.ReadByte());
-				/* for some reason Char is serialized */
-				/*} else if (type==typeof(Char)) {
-					return(reader.ReadChar());*/
-				} else if (type==typeof(Decimal)) {
-					return(reader.ReadDecimal());
-				} else if (type==typeof(DateTime)) {
-					return(new DateTime(reader.ReadInt64()));
-				} else if (type==typeof(Double)) {
-					return(reader.ReadDouble());
-				} else if (type==typeof(Int16)) {
-					return(reader.ReadInt16());
-				} else if (type==typeof(Int32)) {
-					return(reader.ReadInt32());
-				} else if (type==typeof(Int64)) {
-					return(reader.ReadInt64());
-				} else if (type==typeof(SByte)) {
-					return(reader.ReadSByte());
-				} else if (type==typeof(Single)) {
-					return(reader.ReadSingle());
-				} else if (type==typeof(String)) {
-					return(reader.ReadString());
-				} else if (type==typeof(TimeSpan)) {
-					return(new TimeSpan(reader.ReadInt64()));
-				} else if (type==typeof(UInt16)) {
-					return(reader.ReadUInt16());
-				} else if (type==typeof(UInt32)) {
-					return(reader.ReadUInt32());
-				} else if (type==typeof(UInt64)) {
-					return(reader.ReadUInt64());
-				} else {
-					/* non-intrinsic types are
-					 * serialized
-					 */
-					object obj=formatter.Deserialize(reader.BaseStream);
-					if(obj.GetType() != type) {
-						/* We got a bogus
-						 * object.  This
-						 * exception is the
-						 * best match I could
-						 * find.  (.net seems
-						 * to throw
-						 * BadImageFormatException,
-						 * which the docs
-						 * state is used when
-						 * file or dll images
-						 * cant be loaded by
-						 * the runtime.)
-						 */
-						throw new InvalidOperationException("Deserialized object is wrong type");
-					}
-					
-					return(obj);
-				}
+
+				return ReadValueVer1 (types[type_index]);
 			}
 		}