2 // SerializedFromResXHandler.cs : Handles a resource that was stored in a
3 // resx file by means of serialization.
6 // Gary Barnett (gary.barnett.mono@gmail.com)
8 // Copyright (C) Gary Barnett (2012)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Reflection;
31 using System.ComponentModel.Design;
32 using System.ComponentModel;
33 using System.Runtime.Serialization;
34 using System.Runtime.Serialization.Formatters.Binary;
37 using System.Runtime.Serialization.Formatters.Soap;
39 namespace System.Resources {
40 internal class SerializedFromResXHandler : ResXDataNodeHandler, IWritableHandler {
44 CustomBinder binder; // so type set after first call
46 public SerializedFromResXHandler (string data, string _mime_type)
49 mime_type = _mime_type;
52 #region implemented abstract members of System.Resources.ResXDataNodeHandler
53 public override object GetValue (ITypeResolutionService typeResolver)
55 return DeserializeObject (typeResolver);
58 public override object GetValue (AssemblyName [] assemblyNames)
60 return DeserializeObject (new AssemblyNamesTypeResolutionService (assemblyNames));
63 public override string GetValueTypeName (ITypeResolutionService typeResolver)
65 return InternalGetValueType (typeResolver);
68 public override string GetValueTypeName (AssemblyName [] assemblyNames)
70 return InternalGetValueType (null);
74 #region IWritableHandler implementation
75 public string DataString {
82 string InternalGetValueType (ITypeResolutionService typeResolver)
84 object retrievedObject;
86 retrievedObject = DeserializeObject (typeResolver);
88 return typeof (object).AssemblyQualifiedName;
91 if (retrievedObject == null)
94 return retrievedObject.GetType ().AssemblyQualifiedName;
97 object DeserializeObject (ITypeResolutionService typeResolver)
100 if (mime_type == ResXResourceWriter.SoapSerializedObjectMimeType) {
101 //FIXME: theres a test in the suite to check that a type converter converts from invariant string
102 //do i need to take the string culture into consideration here?
103 SoapFormatter soapF = new SoapFormatter ();
105 binder = new CustomBinder (typeResolver);
106 soapF.Binder = binder;
107 byte [] data = Convert.FromBase64String (dataString);
108 using (MemoryStream s = new MemoryStream (data)) {
109 return soapF.Deserialize (s);
111 } else if (mime_type == ResXResourceWriter.BinSerializedObjectMimeType) {
112 BinaryFormatter binF = new BinaryFormatter ();
114 binder = new CustomBinder (typeResolver);
115 binF.Binder = binder;
116 byte [] data = Convert.FromBase64String (dataString);
117 using (MemoryStream s = new MemoryStream (data)) {
118 return binF.Deserialize (s);
120 } else // invalid mime_type
122 } catch (SerializationException ex) {
123 if (ex.Message.StartsWith ("Couldn't find assembly"))
124 throw new ArgumentException (ex.Message);
130 sealed class CustomBinder : SerializationBinder
132 ITypeResolutionService typeResolver;
134 public CustomBinder (ITypeResolutionService _typeResolver)
137 typeResolver = _typeResolver;
140 public override Type BindToType(string assemblyName, string typeName)
142 Type typeToUse = null;
144 string typeString = String.Format("{0}, {1}", typeName, assemblyName);
146 if (typeResolver != null)
147 typeToUse = typeResolver.GetType (typeString);
149 if (typeToUse == null)
150 typeToUse = Type.GetType(typeString);