2 * monoresgen: convert between the resource formats (.txt, .resources, .resx).
4 * Copyright (c) 2002 Ximian, Inc
6 * Author: Paolo Molaro (lupus@ximian.com)
11 * * escape/unescape in the .txt reader/writer to be able to roundtrip values with newlines
12 * (unlike the MS ResGen utility)
13 * * add .po format to help traslators on unixy systems
18 using System.Collections;
19 using System.Resources;
20 using System.Reflection;
29 * We load the ResX format stuff on demand, since the classes are in
30 * System.Windows.Forms (!!!) and we can't depend on that assembly in mono, yet.
32 static void LoadResX () {
36 swf = Assembly.LoadWithPartialName ("System.Windows.Forms");
37 resxr = swf.GetType ("System.Resources.ResXResourceReader");
38 resxw = swf.GetType ("System.Resources.ResXResourceWriter");
39 } catch (Exception e) {
40 throw new Exception ("Cannot load support for ResX format: " + e.Message);
44 static void Usage () {
45 string Usage = @"Mono Resource Generator version 0.1
47 monoresgen source.ext [dest.ext]
48 monoresgen /compile source.ext[,dest.resources] [...]
50 Convert a resource file from one format to another.
51 The currently supported formats are: '.txt' '.resources' '.resx'.
52 If the destination file is not specified, source.resources will be used.
53 The /compile option takes a list of .resX or .txt files to convert to
54 .resources files in one bulk operation, replacing .ext with .resources for
57 Console.WriteLine( Usage );
60 static IResourceReader GetReader (Stream stream, string name) {
61 string format = Path.GetExtension (name);
62 switch (format.ToLower ()) {
65 return new TxtResourceReader (stream);
67 return new ResourceReader (stream);
70 return (IResourceReader)Activator.CreateInstance (resxr, new object[] {stream});
72 throw new Exception ("Unknown format in file " + name);
76 static IResourceWriter GetWriter (Stream stream, string name) {
77 string format = Path.GetExtension (name);
78 switch (format.ToLower ()) {
81 return new TxtResourceWriter (stream);
83 return new ResourceWriter (stream);
86 return (IResourceWriter)Activator.CreateInstance (resxw, new object[] {stream});
88 throw new Exception ("Unknown format in file " + name);
92 static int CompileResourceFile(string sname, string dname ) {
94 FileStream source, dest;
95 IResourceReader reader;
96 IResourceWriter writer;
98 source = new FileStream (sname, FileMode.Open, FileAccess.Read);
99 dest = new FileStream (dname, FileMode.OpenOrCreate, FileAccess.Write);
101 reader = GetReader (source, sname);
102 writer = GetWriter (dest, dname);
105 foreach (DictionaryEntry e in reader) {
107 object val = e.Value;
109 writer.AddResource ((string)e.Key, (string)e.Value);
111 writer.AddResource ((string)e.Key, e.Value);
113 Console.WriteLine( "Read in {0} resources from '{1}'", rescount, sname );
117 Console.WriteLine("Writing resource file... Done.");
118 } catch (Exception e) {
119 Console.WriteLine ("Error: {0}", e.Message);
125 static int Main (string[] args) {
126 string sname = "", dname = "";
127 if ((int) args.Length < 1 || args[0] == "-h" || args[0] == "-?" || args[0] == "/h" || args[0] == "/?") {
131 if (args[0] == "/compile" || args[0] == "-compile") {
132 for ( int i=1; i< args.Length; i++ ) {
133 if ( args[i].IndexOf(",") != -1 ){
134 string[] pair = args[i].Split(',');
138 Console.WriteLine(@"error: You must specify an input & outfile file name like this:");
139 Console.WriteLine("inFile.txt,outFile.resources." );
140 Console.WriteLine("You passed in '{0}'.", args[i] );
145 dname = Path.ChangeExtension (sname, "resources");
147 int ret = CompileResourceFile( sname, dname );
155 else if (args.Length == 1) {
157 dname = Path.ChangeExtension (sname, "resources");
158 } else if (args.Length != 2) {
165 return CompileResourceFile( sname, dname );
169 class TxtResourceWriter : IResourceWriter {
172 public TxtResourceWriter (Stream stream) {
173 s = new StreamWriter (stream);
176 public void AddResource (string name, byte[] value) {
177 throw new Exception ("Binary data not valid in a text resource file");
180 public void AddResource (string name, object value) {
181 if (value is string) {
182 AddResource (name, (string)value);
185 throw new Exception ("Objects not valid in a text resource file");
188 /* FIXME: handle newlines */
189 public void AddResource (string name, string value) {
190 s.WriteLine ("{0}={1}", name, value);
193 public void Close () {
197 public void Dispose () {}
199 public void Generate () {}
202 class TxtResourceReader : IResourceReader {
206 public TxtResourceReader (Stream stream) {
207 data = new Hashtable ();
212 public virtual void Close () {
215 public IDictionaryEnumerator GetEnumerator() {
216 return data.GetEnumerator ();
220 StreamReader reader = new StreamReader (s);
221 string line, key, val;
222 int epos, line_num = 0;
223 while ((line = reader.ReadLine ()) != null) {
226 if (line.Length == 0 || line [0] == '#' ||
229 epos = line.IndexOf ('=');
231 throw new Exception ("Invalid format at line " + line_num);
232 key = line.Substring (0, epos);
233 val = line.Substring (epos + 1);
237 throw new Exception ("Key is empty at line " + line_num);
242 IEnumerator IEnumerable.GetEnumerator () {
243 return ((IResourceReader) this).GetEnumerator();
246 void IDisposable.Dispose () {}