Handle windows paths in ResXFileRef, for conversion to string case
[mono.git] / mcs / class / System.Windows.Forms / System.Resources / ResXFileRef.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Peter Bartok    (pbartok@novell.com)
24 //      Gert Driesen    (drieseng@users.sourceforge.net)
25 //
26
27 using System;
28 using System.ComponentModel;
29 using System.Drawing;
30 using System.IO;
31 using System.Reflection;
32 using System.Text;
33
34 namespace System.Resources {
35         [Serializable]
36         [TypeConverter(typeof(ResXFileRef.Converter))]
37 #if INSIDE_SYSTEM_WEB
38         internal
39 #else
40         public 
41 #endif
42         class ResXFileRef {
43 #if INSIDE_SYSTEM_WEB
44                 internal
45 #else
46                 public
47 #endif
48                 class Converter : TypeConverter {
49                         public Converter() {
50                         }
51
52                         public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
53                                 return sourceType == typeof(string);
54                         }
55
56                         public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
57                                 return destinationType == typeof(string);
58                         }
59
60                         public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) {
61                                 byte[]          buffer;
62
63                                 if ( !(value is String)) {
64                                         return null;
65                                 }
66
67                                 string [] parts = ResXFileRef.Parse ((string) value);
68                                 if (parts.Length == 1)
69                                         throw new ArgumentException ("value");
70
71                                 string filename = parts [0];
72                                 if (Path.DirectorySeparatorChar == '/')
73                                         filename = filename.Replace ("\\", "/");
74
75                                 Type type = Type.GetType (parts [1]);
76                                 if (type == typeof(string)) {
77                                         Encoding encoding;
78                                         if (parts.Length > 2) {
79                                                 encoding = Encoding.GetEncoding (parts [2]);
80                                         } else {
81                                                 encoding = Encoding.Default;
82                                         }
83
84                                         using (TextReader reader = new StreamReader(filename, encoding)) {
85                                                 return reader.ReadToEnd();
86                                         }
87                                 }
88
89                                 using (FileStream file = new FileStream (filename, FileMode.Open, FileAccess.Read, FileShare.Read)) {
90                                         buffer = new byte [file.Length];
91                                         file.Read(buffer, 0, (int) file.Length);
92                                 }
93
94                                 if (type == typeof(System.Byte[]))
95                                         return buffer;
96
97                                 if (type == typeof (Bitmap) && Path.GetExtension (filename) == ".ico") {
98                                         MemoryStream ms = new MemoryStream (buffer);
99                                         return new Icon (ms).ToBitmap ();
100                                 }
101
102                                 if (type == typeof (MemoryStream))
103                                         return new MemoryStream (buffer);
104
105                                 return Activator.CreateInstance(type, BindingFlags.CreateInstance
106                                         | BindingFlags.Public | BindingFlags.Instance, null, 
107                                         new object[] { new MemoryStream (buffer) }, culture);
108                         }
109
110                         public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) {
111                                 if (destinationType != typeof(String)) {
112                                         return base.ConvertTo (context, culture, value, destinationType);
113                                 }
114
115                                 return ((ResXFileRef)value).ToString();
116                         }
117                 }
118
119                 private string filename;
120                 private string typename;
121                 private Encoding textFileEncoding;
122
123                 public ResXFileRef (string fileName, string typeName)
124                 {
125                         if (fileName == null)
126                                 throw new ArgumentNullException ("fileName");
127                         if (typeName == null)
128                                 throw new ArgumentNullException ("typeName");
129
130                         this.filename = fileName;
131                         this.typename = typeName;
132                 }
133
134                 public ResXFileRef (string fileName, string typeName, Encoding textFileEncoding)
135                         : this (fileName, typeName) 
136                 {
137                         this.textFileEncoding = textFileEncoding;
138                 }
139
140                 public string FileName {
141                         get { return filename; }
142                 }
143
144                 public Encoding TextFileEncoding {
145                         get { return textFileEncoding; }
146                 }
147
148                 public string TypeName {
149                         get { return typename; }
150                 }
151
152                 public override string ToString() {
153                         StringBuilder sb = new StringBuilder ();
154                         if (filename != null) {
155                                 sb.Append (filename);
156                         }
157                         sb.Append (';');
158                         if (typename != null) {
159                                 sb.Append (typename);
160                         }
161                         if (textFileEncoding != null) {
162                                 sb.Append (';');
163                                 sb.Append (textFileEncoding.WebName);
164                         }
165                         return sb.ToString ();
166                 }
167
168                 internal static string [] Parse (string fileRef)
169                 {
170                         // we cannot return ResXFileRef, as that would mean we'd have to
171                         // instantiate the encoding, and we do not always need this
172
173                         if (fileRef == null)
174                                 throw new ArgumentNullException ("fileRef");
175
176                         return fileRef.Split (';');
177                 }
178         }
179 }