5 * Moonlight List (moonlight-list@lists.ximian.com)
7 * Copyright 2009 Novell, Inc. (http://www.novell.com)
9 * See the LICENSE file included with the distribution for details.
18 using System
.Collections
;
19 using System
.Collections
.Generic
;
20 using System
.Diagnostics
;
22 using System
.Resources
;
27 public ZipContent Content { get; private set; }
29 public View (ZipContent content
)
37 public abstract Widget
GetView ();
40 class ViewText
: View
{
41 ScrolledWindow scrolled_window
;
46 public ViewText (ZipContent content
) : base (content
)
50 public ViewText (string text
) : base (null)
53 throw new ArgumentNullException ("text");
57 public override Widget
GetView ()
59 if (scrolled_window
!= null)
60 return scrolled_window
;
62 buffer
= new TextBuffer (new TextTagTable ());
64 view
= new TextView (buffer
);
66 scrolled_window
= new ScrolledWindow ();
67 scrolled_window
.Add (view
);
69 return scrolled_window
;
72 public virtual string Text
{
75 text
= File
.ReadAllText (Content
.UnzippedFilename
);
84 class ViewXaml
: ViewText
{
85 public ViewXaml (ZipContent content
) : base (content
) {}
88 class ViewImage
: View
{
89 ScrolledWindow scrolled_window
;
93 public ViewImage (ZipContent content
) : base (content
)
97 public ViewImage (System
.IO
.Stream stream
) : base (null)
99 pixbuf
= new Gdk
.Pixbuf (stream
);
102 public override Widget
GetView ()
104 if (scrolled_window
!= null)
105 return scrolled_window
;
107 image
= new Gtk
.Image (pixbuf
);
108 scrolled_window
= new ScrolledWindow ();
109 scrolled_window
.AddWithViewport (image
);
111 return scrolled_window
;
115 class ViewCode
: View
{
118 ScrolledWindow scrolled_tree
;
119 MethodDefinition method
;
120 public ViewCode (MethodDefinition method
)
122 this.method
= method
;
125 public override Widget
GetView ()
127 if (scrolled_tree
!= null)
128 return scrolled_tree
;
131 store
= new ListStore (typeof (string), typeof (string), typeof (string));
132 tree
= new TreeView ();
134 tree
.AppendColumn ("Offset", new CellRendererText (), "text", 0);
135 tree
.AppendColumn ("Instruction", new CellRendererText (), "text", 1);
136 tree
.AppendColumn ("Operand", new CellRendererText (), "text", 2);
137 tree
.HeadersVisible
= true;
138 scrolled_tree
= new ScrolledWindow ();
139 scrolled_tree
.Add (tree
);
141 Mono
.Cecil
.Cil
.MethodBody body
= method
.Body
;
142 Mono
.Cecil
.Cil
.Instruction instr
;
144 for (int i
= 0; i
< body
.Instructions
.Count
; i
++) {
145 instr
= body
.Instructions
[i
];
147 store
.AppendValues ("IL_" + instr
.Offset
.ToString ("0000"), instr
.OpCode
.ToString (), FormatOperand (instr
.Operand
));
150 return scrolled_tree
;
153 string FormatOperand (object operand
)
155 Mono
.Cecil
.Cil
.Instruction instr
;
160 instr
= operand
as Mono
.Cecil
.Cil
.Instruction
;
162 return "IL_" + instr
.Offset
.ToString ("0000");
164 return operand
.ToString ();
170 class ViewResource
: View
{
174 ScrolledWindow scrolled_tree
;
178 public ViewResource (Resource resource
) : base ()
180 this.resource
= resource
;
183 public override Widget
GetView ()
189 box
= new VBox (false, 10);
190 store
= new ListStore (typeof (string), typeof (string), typeof (object));
191 tree
= new TreeView ();
193 tree
.AppendColumn ("Name", new CellRendererText (), "text", 0);
194 tree
.AppendColumn ("Type", new CellRendererText (), "text", 1);
195 tree
.HeadersVisible
= true;
196 tree
.CursorChanged
+= HandleCursorChanged
;
197 scrolled_tree
= new ScrolledWindow ();
198 scrolled_tree
.Add (tree
);
199 box
.PackStart (scrolled_tree
, true, true, 0);
202 EmbeddedResource embed
= resource
as EmbeddedResource
;
204 using (MemoryStream stream
= new MemoryStream (embed
.Data
)) {
205 using (ResourceReader reader
= new ResourceReader (stream
)) {
206 foreach (DictionaryEntry obj
in reader
) {
207 store
.AppendValues (obj
.Key
.ToString (), obj
.Value
.GetType ().FullName
, obj
.Value
);
212 Console
.WriteLine ("Don't know how to handle a resource whose type is {0}", resource
.GetType ().FullName
);
218 void HandleCursorChanged (object sender
, EventArgs e
)
220 TreeSelection selection
= tree
.Selection
;
228 if (!selection
.GetSelected (out model
, out iter
))
232 store
.GetValue (iter
, 0, ref v
);
233 name
= v
.Val
as string;
235 store
.GetValue (iter
, 1, ref v
);
236 type
= v
.Val
as string;
238 store
.GetValue (iter
, 2, ref v
);
241 // Create a view based on what we got
244 case "System.IO.MemoryStream":
245 MemoryStream stream
= value as MemoryStream
;
246 if (name
.EndsWith (".xaml")) {
248 using (MemoryStream clone
= new MemoryStream (stream
.ToArray ())) {
249 using (StreamReader t
= new StreamReader (clone
)) {
250 view
= new ViewText (t
.ReadToEnd ());
253 } else if (name
.EndsWith (".png") || name
.EndsWith (".jpg")) {
254 using (MemoryStream clone
= new MemoryStream (stream
.ToArray ())) {
255 view
= new ViewImage (clone
);
258 Console
.WriteLine ("Don't know what to do with a {0} in a {1}", name
, type
);
261 case "System.String":
263 view
= new ViewText ((string) value);
266 Console
.WriteLine ("Unhandled case: {0}", type
);
270 // Remove previous views and add the new one
272 while (box
.Children
.Length
> 1)
273 box
.Remove (box
.Children
[1]);
276 box
.PackStart (view
.GetView (), true, true, 0);
282 class ViewAssembly
: View
{
286 ScrolledWindow scrolled_tree
;
287 AssemblyDefinition assembly
;
289 static Gdk
.Pixbuf classPixbuf
, delegatePixbuf
, enumPixbuf
;
290 static Gdk
.Pixbuf eventPixbuf
, fieldPixbuf
, interfacePixbuf
;
291 static Gdk
.Pixbuf methodPixbuf
, namespacePixbuf
, propertyPixbuf
;
292 static Gdk
.Pixbuf attributePixbuf
, structPixbuf
, assemblyPixbuf
;
294 static ViewAssembly ()
296 System
.Reflection
.Assembly ta
= typeof (ViewAssembly
).Assembly
;
297 classPixbuf
= new Gdk
.Pixbuf (ta
, "c.gif");
298 delegatePixbuf
= new Gdk
.Pixbuf (ta
, "d.gif");
299 enumPixbuf
= new Gdk
.Pixbuf (ta
, "en.gif");
300 eventPixbuf
= new Gdk
.Pixbuf (ta
, "e.gif");
301 fieldPixbuf
= new Gdk
.Pixbuf (ta
, "f.gif");
302 interfacePixbuf
= new Gdk
.Pixbuf (ta
, "i.gif");
303 methodPixbuf
= new Gdk
.Pixbuf (ta
, "m.gif");
304 namespacePixbuf
= new Gdk
.Pixbuf (ta
, "n.gif");
305 propertyPixbuf
= new Gdk
.Pixbuf (ta
, "p.gif");
306 attributePixbuf
= new Gdk
.Pixbuf (ta
, "r.gif");
307 structPixbuf
= new Gdk
.Pixbuf (ta
, "s.gif");
308 assemblyPixbuf
= new Gdk
.Pixbuf (ta
, "y.gif");
311 public ViewAssembly (ZipContent content
) : base (content
) {}
313 public override Widget
GetView ()
323 store
= new TreeStore (typeof (string), typeof (string), typeof (string), typeof (object), typeof (Gdk
.Pixbuf
));
324 tree
= new TreeView ();
326 tree
.AppendColumn ("Icon", new CellRendererPixbuf (), "pixbuf", 4);
327 tree
.AppendColumn ("Name", new CellRendererText (), "text", 0);
328 tree
.AppendColumn ("Type", new CellRendererText (), "text", 1);
329 tree
.AppendColumn ("Info", new CellRendererText (), "text", 2);
330 tree
.HeadersVisible
= true;
331 tree
.CursorChanged
+= HandleCursorChanged
;
332 scrolled_tree
= new ScrolledWindow ();
333 scrolled_tree
.Add (tree
);
334 box
.PackStart (scrolled_tree
, true, true, 0);
336 if (assembly
== null)
337 assembly
= AssemblyFactory
.GetAssembly (Content
.UnzippedFilename
);
340 // first get a list of resources in the assembly
341 iter
= store
.AppendValues ("Resources");
342 foreach (Mono
.Cecil
.Resource res
in assembly
.MainModule
.Resources
) {
343 store
.AppendValues (iter
, res
.Name
, "Resource", "", res
);
347 Gtk
.TreeIter classes
= store
.AppendValues ("Classes");
348 foreach (TypeDefinition type
in assembly
.MainModule
.Types
) {
349 Gtk
.TreeIter cl
= store
.AppendValues (classes
, type
.FullName
, "Type", "", type
, classPixbuf
);
350 List
<MethodDefinition
> shown_methods
= new List
<MethodDefinition
> ();
351 foreach (PropertyDefinition property
in type
.Properties
) {
352 Gtk
.TreeIter prop
= store
.AppendValues (cl
, property
.Name
, "Property", "", property
, propertyPixbuf
);
353 if (property
.GetMethod
!= null) {
354 store
.AppendValues (prop
, FormatMethod (property
.GetMethod
), "Getter", "", property
.GetMethod
, methodPixbuf
);
355 shown_methods
.Add (property
.GetMethod
);
357 if (property
.SetMethod
!= null) {
358 store
.AppendValues (prop
, FormatMethod (property
.SetMethod
), "Setter", "", property
.SetMethod
, methodPixbuf
);
359 shown_methods
.Add (property
.SetMethod
);
362 foreach (EventDefinition ev
in type
.Events
) {
363 Gtk
.TreeIter evIter
= store
.AppendValues (cl
, ev
.Name
, "Event", "", ev
, eventPixbuf
);
364 if (ev
.AddMethod
!= null) {
365 store
.AppendValues (evIter
, FormatMethod (ev
.AddMethod
), "Adder", "", ev
.AddMethod
, methodPixbuf
);
366 shown_methods
.Add (ev
.AddMethod
);
368 if (ev
.RemoveMethod
!= null) {
369 store
.AppendValues (evIter
, FormatMethod (ev
.RemoveMethod
), "Remover", "", ev
.RemoveMethod
, methodPixbuf
);
370 shown_methods
.Add (ev
.RemoveMethod
);
372 if (ev
.InvokeMethod
!= null) {
373 store
.AppendValues (evIter
, FormatMethod (ev
.InvokeMethod
), "Invoker", "", ev
.InvokeMethod
, methodPixbuf
);
374 shown_methods
.Add (ev
.InvokeMethod
);
377 foreach (MethodDefinition method
in type
.Methods
) {
378 if (shown_methods
.Contains (method
))
380 store
.AppendValues (cl
, FormatMethod (method
), "Method", "", method
, methodPixbuf
);
382 foreach (MethodDefinition method
in type
.Constructors
) {
383 store
.AppendValues (cl
, FormatMethod (method
), "Constructor", "", method
, methodPixbuf
);
385 foreach (FieldDefinition field
in type
.Fields
) {
386 store
.AppendValues (cl
, field
.FieldType
.Name
+ " " + field
.Name
, "Field", "", field
, fieldPixbuf
);
392 string FormatMethod (MethodDefinition method
)
394 StringBuilder result
= new StringBuilder ();
396 result
.Append (method
.ReturnType
.ReturnType
.Name
);
398 result
.Append (method
.Name
);
401 for (int i
= 0; i
< method
.Parameters
.Count
- 1; i
++) {
403 result
.Append (", ");
404 result
.Append (method
.Parameters
[i
].ParameterType
.Name
);
406 result
.Append (method
.Parameters
[i
].Name
);
410 return result
.ToString ();
413 void HandleCursorChanged (object sender
, EventArgs e
)
415 TreeSelection selection
= tree
.Selection
;
422 if (!selection
.GetSelected (out model
, out iter
))
425 // Create a view based on what we got
428 store
.GetValue (iter
, 2, ref v
);
429 info
= v
.Val
as string;
431 store
.GetValue (iter
, 1, ref v
);
432 type
= v
.Val
as string;
436 Console
.WriteLine ("JB, We need your decompiler.");
441 store
.GetValue (iter
, 3, ref v
);
442 res
= v
.Val
as Resource
;
444 view
= new ViewResource (res
);
446 Console
.WriteLine ("{0} didn't have a Resource, it had a {1}.", type
, v
.Val
== null ? "null" : v
.Val
.GetType ().ToString ());
456 MethodDefinition def
;
458 store
.GetValue (iter
, 3, ref v
);
459 def
= v
.Val
as MethodDefinition
;
461 view
= new ViewCode (def
);
463 Console
.WriteLine ("{0} didn't have a MethodDefinition.", type
);
467 Console
.WriteLine ("Unhandled case: {0}", type
);
471 // Remove old views and add the new one
473 while (box
.Children
.Length
> 1)
474 box
.Remove (box
.Children
[1]);
477 box
.PackStart (view
.GetView (), true, true, 0);