diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:12:16 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:12:16 +0000 |
commit | 920c091ac3ee15079194c82ae8a7a18215f3f23c (patch) | |
tree | d28515d1e7732e2b6d077df1b4855ace3f4ac84f /tools/stats_viewer | |
parent | ae2c20f398933a9e86c387dcc465ec0f71065ffc (diff) | |
download | chromium_src-920c091ac3ee15079194c82ae8a7a18215f3f23c.zip chromium_src-920c091ac3ee15079194c82ae8a7a18215f3f23c.tar.gz chromium_src-920c091ac3ee15079194c82ae8a7a18215f3f23c.tar.bz2 |
Add tools to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/stats_viewer')
19 files changed, 3647 insertions, 0 deletions
diff --git a/tools/stats_viewer/OpenDialog.Designer.cs b/tools/stats_viewer/OpenDialog.Designer.cs new file mode 100644 index 0000000..3ef7a27 --- /dev/null +++ b/tools/stats_viewer/OpenDialog.Designer.cs @@ -0,0 +1,113 @@ +// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+namespace StatsViewer
+{
+ partial class OpenDialog
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.name_box_ = new System.Windows.Forms.TextBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.button1 = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // name_box_
+ //
+ this.name_box_.Location = new System.Drawing.Point(108, 25);
+ this.name_box_.Name = "name_box_";
+ this.name_box_.Size = new System.Drawing.Size(180, 20);
+ this.name_box_.TabIndex = 0;
+ this.name_box_.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnKeyUp);
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(12, 28);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(91, 13);
+ this.label1.TabIndex = 1;
+ this.label1.Text = "Stats File to Open";
+ //
+ // button1
+ //
+ this.button1.Location = new System.Drawing.Point(108, 61);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(75, 23);
+ this.button1.TabIndex = 2;
+ this.button1.Text = "OK";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_Click);
+ //
+ // OpenDialog
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(303, 94);
+ this.Controls.Add(this.button1);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.name_box_);
+ this.Name = "OpenDialog";
+ this.Text = "OpenDialog";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TextBox name_box_;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Button button1;
+ }
+}
\ No newline at end of file diff --git a/tools/stats_viewer/OpenDialog.cs b/tools/stats_viewer/OpenDialog.cs new file mode 100644 index 0000000..aac49a7 --- /dev/null +++ b/tools/stats_viewer/OpenDialog.cs @@ -0,0 +1,70 @@ +// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+namespace StatsViewer
+{
+ public partial class OpenDialog : Form
+ {
+ public OpenDialog()
+ {
+ InitializeComponent();
+ }
+
+ /// <summary>
+ /// Get the user selected filename
+ /// </summary>
+ public string FileName
+ {
+ get {
+ return this.name_box_.Text;
+ }
+ }
+
+ private void button1_Click(object sender, EventArgs e)
+ {
+ this.Close();
+ }
+
+ private void OnKeyUp(object sender, KeyEventArgs e)
+ {
+ if (e.KeyCode == Keys.Enter)
+ {
+ this.Close();
+ }
+ }
+ }
+}
\ No newline at end of file diff --git a/tools/stats_viewer/OpenDialog.resx b/tools/stats_viewer/OpenDialog.resx new file mode 100644 index 0000000..ff31a6d --- /dev/null +++ b/tools/stats_viewer/OpenDialog.resx @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file diff --git a/tools/stats_viewer/Properties/AssemblyInfo.cs b/tools/stats_viewer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8ffae14 --- /dev/null +++ b/tools/stats_viewer/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("StatsViewer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Google")]
+[assembly: AssemblyProduct("StatsViewer")]
+[assembly: AssemblyCopyright("Copyright © Google 2007")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("0c5760e1-3ada-48e2-800d-5b104bef4a95")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/tools/stats_viewer/Properties/Resources.Designer.cs b/tools/stats_viewer/Properties/Resources.Designer.cs new file mode 100644 index 0000000..4195c5f --- /dev/null +++ b/tools/stats_viewer/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.832
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace StatsViewer.Properties
+{
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("StatsViewer.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/tools/stats_viewer/Properties/Resources.resx b/tools/stats_viewer/Properties/Resources.resx new file mode 100644 index 0000000..ffecec8 --- /dev/null +++ b/tools/stats_viewer/Properties/Resources.resx @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file diff --git a/tools/stats_viewer/Properties/Settings.Designer.cs b/tools/stats_viewer/Properties/Settings.Designer.cs new file mode 100644 index 0000000..221765a --- /dev/null +++ b/tools/stats_viewer/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.832
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace StatsViewer.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/tools/stats_viewer/Properties/Settings.settings b/tools/stats_viewer/Properties/Settings.settings new file mode 100644 index 0000000..abf36c5 --- /dev/null +++ b/tools/stats_viewer/Properties/Settings.settings @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile>
diff --git a/tools/stats_viewer/Resources.Designer.cs b/tools/stats_viewer/Resources.Designer.cs new file mode 100644 index 0000000..2d915e0 --- /dev/null +++ b/tools/stats_viewer/Resources.Designer.cs @@ -0,0 +1,77 @@ +//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.832
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace StatsViewer {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("StatsViewer.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ internal static System.Drawing.Bitmap kitten {
+ get {
+ object obj = ResourceManager.GetObject("kitten", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ internal static System.Drawing.Bitmap kittenbackground {
+ get {
+ object obj = ResourceManager.GetObject("kittenbackground", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+ }
+}
diff --git a/tools/stats_viewer/Resources.resx b/tools/stats_viewer/Resources.resx new file mode 100644 index 0000000..9486b21 --- /dev/null +++ b/tools/stats_viewer/Resources.resx @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <data name="kitten" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>Resources\kitten.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ </data>
+ <data name="kittenbackground" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>Resources\kittenbackground.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ </data>
+</root>
\ No newline at end of file diff --git a/tools/stats_viewer/Resources/kitten.png b/tools/stats_viewer/Resources/kitten.png Binary files differnew file mode 100644 index 0000000..51cc9b8 --- /dev/null +++ b/tools/stats_viewer/Resources/kitten.png diff --git a/tools/stats_viewer/Resources/kittenbackground.png b/tools/stats_viewer/Resources/kittenbackground.png Binary files differnew file mode 100644 index 0000000..09a7268 --- /dev/null +++ b/tools/stats_viewer/Resources/kittenbackground.png diff --git a/tools/stats_viewer/program.cs b/tools/stats_viewer/program.cs new file mode 100644 index 0000000..2668cec --- /dev/null +++ b/tools/stats_viewer/program.cs @@ -0,0 +1,48 @@ +// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+using System;
+using System.Windows.Forms;
+
+namespace StatsViewer
+{
+ static class Program
+ {
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new StatsViewer());
+ }
+ }
+}
\ No newline at end of file diff --git a/tools/stats_viewer/stats_table.cs b/tools/stats_viewer/stats_table.cs new file mode 100644 index 0000000..a2f87cf --- /dev/null +++ b/tools/stats_viewer/stats_table.cs @@ -0,0 +1,571 @@ +// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace StatsViewer
+{
+ /// <summary>
+ /// The stats table shared memory segment contains this
+ /// header structure.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct StatsFileHeader {
+ public int version;
+ public int size;
+ public int max_counters;
+ public int max_threads;
+ };
+
+ /// <summary>
+ /// An entry in the StatsTable.
+ /// </summary>
+ class StatsTableEntry {
+ public StatsTableEntry(int id, string name, StatsTable table) {
+ id_ = id;
+ name_ = name;
+ table_ = table;
+ }
+
+ /// <summary>
+ /// The unique id for this entry
+ /// </summary>
+ public int id { get { return id_; } }
+
+ /// <summary>
+ /// The name for this entry.
+ /// </summary>
+ public string name { get { return name_; } }
+
+ /// <summary>
+ /// The value of this entry now.
+ /// </summary>
+ public int GetValue(int filter_pid) {
+ return table_.GetValue(id_, filter_pid);
+ }
+
+ private int id_;
+ private string name_;
+ private StatsTable table_;
+ }
+
+ // An interface for StatsCounters
+ interface IStatsCounter {
+ // The name of the counter
+ string name { get; }
+ }
+
+ // A counter.
+ class StatsCounter : IStatsCounter {
+ public StatsCounter(StatsTableEntry entry) {
+ entry_ = entry;
+ }
+
+ public string name {
+ get {
+ return entry_.name;
+ }
+ }
+
+ public int GetValue(int filter_pid) {
+ return entry_.GetValue(filter_pid);
+ }
+
+ private StatsTableEntry entry_;
+ }
+
+ // A timer.
+ class StatsTimer : IStatsCounter {
+ public StatsTimer(StatsTableEntry entry)
+ {
+ entry_ = entry;
+ }
+
+ public string name {
+ get {
+ return entry_.name;
+ }
+ }
+
+ public int GetValue(int filter_pid) {
+ return entry_.GetValue(filter_pid);
+ }
+
+ private StatsTableEntry entry_;
+ }
+
+ // A rate.
+ class StatsCounterRate : IStatsCounter
+ {
+ public StatsCounterRate(StatsCounter counter, StatsTimer timer) {
+ counter_ = counter;
+ timer_ = timer;
+ }
+
+ public string name { get { return counter_.name; } }
+
+ public int GetCount(int filter_pid) {
+ return counter_.GetValue(filter_pid);
+ }
+
+ public int GetTime(int filter_pid) {
+ return timer_.GetValue(filter_pid);
+ }
+
+ private StatsCounter counter_;
+ private StatsTimer timer_;
+ }
+
+ /// <summary>
+ /// This is a C# reader for the chrome stats_table.
+ /// </summary>
+ class StatsTable {
+ internal const int kMaxThreadNameLength = 32;
+ internal const int kMaxCounterNameLength = 32;
+
+ /// <summary>
+ /// Open a StatsTable
+ /// </summary>
+ public StatsTable() {
+ }
+
+ #region Public Properties
+ /// <summary>
+ /// Get access to the counters in the table.
+ /// </summary>
+ public StatsTableCounters Counters() {
+ return new StatsTableCounters(this);
+ }
+
+ /// <summary>
+ /// Get access to the processes in the table
+ /// </summary>
+ public ICollection Processes {
+ get {
+ return new StatsTableProcesses(this);
+ }
+ }
+ #endregion
+
+ #region Internal Properties
+ //
+ // The internal methods are accessible to the enumerators
+ // and helper classes below.
+ //
+
+ /// <summary>
+ /// Access to the table header
+ /// </summary>
+ internal StatsFileHeader Header {
+ get { return header_; }
+ }
+
+ /// <summary>
+ /// Get the offset of the ThreadName table
+ /// </summary>
+ internal long ThreadNamesOffset {
+ get {
+ return memory_.ToInt64() + Marshal.SizeOf(typeof(StatsFileHeader));
+ }
+ }
+
+ /// <summary>
+ /// Get the offset of the PIDs table
+ /// </summary>
+ internal long PidsOffset {
+ get {
+ long offset = ThreadNamesOffset;
+ // Thread names table
+ offset += AlignedSize(header_.max_threads * kMaxThreadNameLength * 2);
+ // Thread TID table
+ offset += AlignedSize(header_.max_threads *
+ Marshal.SizeOf(typeof(int)));
+ return offset;
+ }
+ }
+
+ /// <summary>
+ /// Get the offset of the CounterName table
+ /// </summary>
+ internal long CounterNamesOffset {
+ get {
+ long offset = PidsOffset;
+ // Thread PID table
+ offset += AlignedSize(header_.max_threads *
+ Marshal.SizeOf(typeof(int)));
+ return offset;
+ }
+ }
+
+ /// <summary>
+ /// Get the offset of the Data table
+ /// </summary>
+ internal long DataOffset {
+ get {
+ long offset = CounterNamesOffset;
+ // Counter names table
+ offset += AlignedSize(header_.max_counters *
+ kMaxCounterNameLength * 2);
+ return offset;
+ }
+ }
+ #endregion
+
+ #region Public Methods
+ /// <summary>
+ /// Opens the memory map
+ /// </summary>
+ /// <returns></returns>
+ /// <param name="name">The name of the file to open</param>
+ public bool Open(string name) {
+ map_handle_ =
+ Win32.OpenFileMapping((int)Win32.MapAccess.FILE_MAP_WRITE, false,
+ name);
+ if (map_handle_ == IntPtr.Zero)
+ return false;
+
+ memory_ =
+ Win32.MapViewOfFile(map_handle_, (int)Win32.MapAccess.FILE_MAP_WRITE,
+ 0,0, 0);
+ if (memory_ == IntPtr.Zero) {
+ Win32.CloseHandle(map_handle_);
+ return false;
+ }
+
+ header_ = (StatsFileHeader)Marshal.PtrToStructure(memory_, header_.GetType());
+ return true;
+ }
+
+ /// <summary>
+ /// Close the mapped file.
+ /// </summary>
+ public void Close() {
+ Win32.UnmapViewOfFile(memory_);
+ Win32.CloseHandle(map_handle_);
+ }
+
+ /// <summary>
+ /// Zero out the stats file.
+ /// </summary>
+ public void Zero() {
+ long offset = DataOffset;
+ for (int threads = 0; threads < header_.max_threads; threads++) {
+ for (int counters = 0; counters < header_.max_counters; counters++) {
+ Marshal.WriteInt32((IntPtr) offset, 0);
+ offset += Marshal.SizeOf(typeof(int));
+ }
+ }
+ }
+
+ /// <summary>
+ /// Get the value for a StatsCounterEntry now.
+ /// </summary>
+ /// <returns></returns>
+ /// <param name="filter_pid">If a specific PID is being queried, filter to this PID. 0 means use all data.</param>
+ /// <param name="id">The id of the CounterEntry to get the value for.</param>
+ public int GetValue(int id, int filter_pid) {
+ long pid_offset = PidsOffset;
+ long data_offset = DataOffset;
+ data_offset += id * (Header.max_threads *
+ Marshal.SizeOf(typeof(int)));
+ int rv = 0;
+ for (int cols = 0; cols < Header.max_threads; cols++)
+ {
+ int pid = Marshal.ReadInt32((IntPtr)pid_offset);
+ if (filter_pid == 0 || filter_pid == pid)
+ {
+ rv += Marshal.ReadInt32((IntPtr)data_offset);
+ }
+ data_offset += Marshal.SizeOf(typeof(int));
+ pid_offset += Marshal.SizeOf(typeof(int));
+ }
+ return rv;
+ }
+ #endregion
+
+ #region Private Methods
+ /// <summary>
+ /// Align to 4-byte boundaries
+ /// </summary>
+ /// <param name="size"></param>
+ /// <returns></returns>
+ private long AlignedSize(long size) {
+ Debug.Assert(sizeof(int) == 4);
+ return size + (sizeof(int) - (size % sizeof(int))) % sizeof(int);
+ }
+ #endregion
+
+ #region Private Members
+ private IntPtr memory_;
+ private IntPtr map_handle_;
+ private StatsFileHeader header_;
+ #endregion
+ }
+
+ /// <summary>
+ /// Enumerable list of Counters in the StatsTable
+ /// </summary>
+ class StatsTableCounters : ICollection {
+ /// <summary>
+ /// Create the list of counters
+ /// </summary>
+ /// <param name="table"></param>
+ /// pid</param>
+ public StatsTableCounters(StatsTable table) {
+ table_ = table;
+ counter_hi_water_mark_ = -1;
+ counters_ = new List<IStatsCounter>();
+ FindCounters();
+ }
+
+ /// <summary>
+ /// Scans the table for new entries.
+ /// </summary>
+ public void Update() {
+ FindCounters();
+ }
+
+ #region IEnumerable Members
+ public IEnumerator GetEnumerator() {
+ return counters_.GetEnumerator();
+ }
+ #endregion
+
+ #region ICollection Members
+ public void CopyTo(Array array, int index) {
+ throw new Exception("The method or operation is not implemented.");
+ }
+
+ public int Count {
+ get {
+ return counters_.Count;
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ }
+
+ public object SyncRoot {
+ get {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ }
+ #endregion
+
+ #region Private Methods
+ /// <summary>
+ /// Create a counter based on an entry
+ /// </summary>
+ /// <param name="id"></param>
+ /// <param name="name"></param>
+ /// <returns></returns>
+ private IStatsCounter NameToCounter(int id, string name)
+ {
+ IStatsCounter rv = null;
+
+ // check if the name has a type encoded
+ if (name.Length > 2 && name[1] == ':')
+ {
+ StatsTableEntry entry = new StatsTableEntry(id, name.Substring(2), table_);
+ switch (name[0])
+ {
+ case 't':
+ rv = new StatsTimer(entry);
+ break;
+ case 'c':
+ rv = new StatsCounter(entry);
+ break;
+ }
+ }
+ else
+ {
+ StatsTableEntry entry = new StatsTableEntry(id, name, table_);
+ rv = new StatsCounter(entry);
+ }
+
+ return rv;
+ }
+
+ // If we have two StatsTableEntries with the same name,
+ // attempt to upgrade them to a higher level type.
+ // Example: A counter + a timer == a rate!
+ private void UpgradeCounter(IStatsCounter old_counter, IStatsCounter counter)
+ {
+ if (old_counter is StatsCounter && counter is StatsTimer)
+ {
+ StatsCounterRate rate = new StatsCounterRate(old_counter as StatsCounter,
+ counter as StatsTimer);
+ counters_.Remove(old_counter);
+ counters_.Add(rate);
+ }
+ else if (old_counter is StatsTimer && counter is StatsCounter)
+ {
+ StatsCounterRate rate = new StatsCounterRate(counter as StatsCounter,
+ old_counter as StatsTimer);
+ counters_.Remove(old_counter);
+ counters_.Add(rate);
+ }
+ }
+
+ /// <summary>
+ /// Find the counters in the table and insert into the counters_
+ /// hash table.
+ /// </summary>
+ private void FindCounters()
+ {
+ Debug.Assert(table_.Header.max_counters > 0);
+
+ int index = counter_hi_water_mark_;
+
+ do
+ {
+ // Find an entry in the table.
+ index++;
+ long offset = table_.CounterNamesOffset +
+ (index * StatsTable.kMaxCounterNameLength * 2);
+ string name = Marshal.PtrToStringUni((IntPtr)offset);
+ if (name.Length == 0)
+ continue;
+
+ // Record that we've already looked at this StatsTableEntry.
+ counter_hi_water_mark_ = index;
+
+ IStatsCounter counter = NameToCounter(index, name);
+
+ if (counter != null)
+ {
+ IStatsCounter old_counter = FindExistingCounter(counter.name);
+ if (old_counter != null)
+ UpgradeCounter(old_counter, counter);
+ else
+ counters_.Add(counter);
+ }
+ } while (index < table_.Header.max_counters - 1);
+ }
+
+ /// <summary>
+ /// Find an existing counter in our table
+ /// </summary>
+ /// <param name="name"></param>
+ private IStatsCounter FindExistingCounter(string name) {
+ foreach (IStatsCounter ctr in counters_)
+ {
+ if (ctr.name == name)
+ return ctr;
+ }
+ return null;
+ }
+ #endregion
+
+ #region Private Members
+ private StatsTable table_;
+ private List<IStatsCounter> counters_;
+ // Highest index of counters processed.
+ private int counter_hi_water_mark_;
+ #endregion
+ }
+
+ /// <summary>
+ /// A collection of processes
+ /// </summary>
+ class StatsTableProcesses : ICollection
+ {
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="table"></param>
+ public StatsTableProcesses(StatsTable table) {
+ table_ = table;
+ pids_ = new List<int>();
+ Initialize();
+ }
+
+ #region ICollection Members
+ public void CopyTo(Array array, int index) {
+ throw new Exception("The method or operation is not implemented.");
+ }
+
+ public int Count {
+ get {
+ return pids_.Count;
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ }
+
+ public object SyncRoot {
+ get {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ }
+ #endregion
+
+ #region IEnumerable Members
+ public IEnumerator GetEnumerator() {
+ return pids_.GetEnumerator();
+ }
+ #endregion
+
+ /// <summary>
+ /// Initialize the pid list.
+ /// </summary>
+ private void Initialize() {
+ long offset = table_.ThreadNamesOffset;
+
+ for (int index = 0; index < table_.Header.max_threads; index++) {
+ string thread_name = Marshal.PtrToStringUni((IntPtr)offset);
+ if (thread_name.Length > 0) {
+ long pidOffset = table_.PidsOffset + index *
+ Marshal.SizeOf(typeof(int));
+ int pid = Marshal.ReadInt32((IntPtr)pidOffset);
+ if (!pids_.Contains(pid))
+ pids_.Add(pid);
+ }
+ offset += StatsTable.kMaxThreadNameLength * 2;
+ }
+ }
+
+ #region Private Members
+ private StatsTable table_;
+ private List<int> pids_;
+ #endregion
+ }
+}
diff --git a/tools/stats_viewer/stats_viewer.Designer.cs b/tools/stats_viewer/stats_viewer.Designer.cs new file mode 100644 index 0000000..f697c5b --- /dev/null +++ b/tools/stats_viewer/stats_viewer.Designer.cs @@ -0,0 +1,417 @@ +// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+namespace StatsViewer
+{
+ partial class StatsViewer
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(StatsViewer));
+ this.listViewCounters = new System.Windows.Forms.ListView();
+ this.columnHeaderName = new System.Windows.Forms.ColumnHeader();
+ this.columnHeaderValue = new System.Windows.Forms.ColumnHeader();
+ this.columnHeaderDelta = new System.Windows.Forms.ColumnHeader();
+ this.pictureBoxTitle = new System.Windows.Forms.PictureBox();
+ this.panelHeader = new System.Windows.Forms.Panel();
+ this.labelKills = new System.Windows.Forms.Label();
+ this.label1 = new System.Windows.Forms.Label();
+ this.labelInterval = new System.Windows.Forms.Label();
+ this.comboBoxFilter = new System.Windows.Forms.ComboBox();
+ this.panelControls = new System.Windows.Forms.Panel();
+ this.buttonExport = new System.Windows.Forms.Button();
+ this.buttonZero = new System.Windows.Forms.Button();
+ this.comboBoxInterval = new System.Windows.Forms.ComboBox();
+ this.labelFilter = new System.Windows.Forms.Label();
+ this.saveFileDialogExport = new System.Windows.Forms.SaveFileDialog();
+ this.menuStrip1 = new System.Windows.Forms.MenuStrip();
+ this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.quitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.listViewRates = new System.Windows.Forms.ListView();
+ this.columnHeaderRateName = new System.Windows.Forms.ColumnHeader();
+ this.columnHeaderRateCount = new System.Windows.Forms.ColumnHeader();
+ this.columnHeaderRateTotaltime = new System.Windows.Forms.ColumnHeader();
+ this.columnHeaderRateAvgTime = new System.Windows.Forms.ColumnHeader();
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ ((System.ComponentModel.ISupportInitialize)(this.pictureBoxTitle)).BeginInit();
+ this.panelHeader.SuspendLayout();
+ this.panelControls.SuspendLayout();
+ this.menuStrip1.SuspendLayout();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // listViewCounters
+ //
+ this.listViewCounters.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+ this.columnHeaderName,
+ this.columnHeaderValue,
+ this.columnHeaderDelta});
+ this.listViewCounters.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.listViewCounters.FullRowSelect = true;
+ this.listViewCounters.Location = new System.Drawing.Point(0, 0);
+ this.listViewCounters.Name = "listViewCounters";
+ this.listViewCounters.Size = new System.Drawing.Size(505, 221);
+ this.listViewCounters.Sorting = System.Windows.Forms.SortOrder.Descending;
+ this.listViewCounters.TabIndex = 0;
+ this.listViewCounters.UseCompatibleStateImageBehavior = false;
+ this.listViewCounters.View = System.Windows.Forms.View.Details;
+ this.listViewCounters.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.column_Click);
+ //
+ // columnHeaderName
+ //
+ this.columnHeaderName.Text = "Counter Name";
+ this.columnHeaderName.Width = 203;
+ //
+ // columnHeaderValue
+ //
+ this.columnHeaderValue.Text = "Value";
+ this.columnHeaderValue.Width = 69;
+ //
+ // columnHeaderDelta
+ //
+ this.columnHeaderDelta.Text = "Delta";
+ this.columnHeaderDelta.Width = 86;
+ //
+ // pictureBoxTitle
+ //
+ this.pictureBoxTitle.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.pictureBoxTitle.BackColor = System.Drawing.Color.Transparent;
+ this.pictureBoxTitle.Image = ((System.Drawing.Image)(resources.GetObject("pictureBoxTitle.Image")));
+ this.pictureBoxTitle.Location = new System.Drawing.Point(257, 0);
+ this.pictureBoxTitle.Name = "pictureBoxTitle";
+ this.pictureBoxTitle.Size = new System.Drawing.Size(248, 86);
+ this.pictureBoxTitle.TabIndex = 1;
+ this.pictureBoxTitle.TabStop = false;
+ //
+ // panelHeader
+ //
+ this.panelHeader.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("panelHeader.BackgroundImage")));
+ this.panelHeader.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
+ this.panelHeader.Controls.Add(this.labelKills);
+ this.panelHeader.Controls.Add(this.label1);
+ this.panelHeader.Controls.Add(this.pictureBoxTitle);
+ this.panelHeader.Dock = System.Windows.Forms.DockStyle.Top;
+ this.panelHeader.Location = new System.Drawing.Point(0, 24);
+ this.panelHeader.Name = "panelHeader";
+ this.panelHeader.Size = new System.Drawing.Size(505, 86);
+ this.panelHeader.TabIndex = 2;
+ //
+ // labelKills
+ //
+ this.labelKills.AutoSize = true;
+ this.labelKills.BackColor = System.Drawing.Color.Transparent;
+ this.labelKills.Font = new System.Drawing.Font("Arial", 9.75F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.labelKills.Location = new System.Drawing.Point(12, 33);
+ this.labelKills.Name = "labelKills";
+ this.labelKills.Size = new System.Drawing.Size(280, 16);
+ this.labelKills.TabIndex = 3;
+ this.labelKills.Text = "During the World Wide Wait, God Kills Kittens.";
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.BackColor = System.Drawing.Color.Transparent;
+ this.label1.Font = new System.Drawing.Font("Arial", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label1.Location = new System.Drawing.Point(12, 9);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(140, 24);
+ this.label1.TabIndex = 2;
+ this.label1.Text = "Chrome Varz";
+ //
+ // labelInterval
+ //
+ this.labelInterval.AutoSize = true;
+ this.labelInterval.Location = new System.Drawing.Point(11, 9);
+ this.labelInterval.Name = "labelInterval";
+ this.labelInterval.Size = new System.Drawing.Size(73, 13);
+ this.labelInterval.TabIndex = 3;
+ this.labelInterval.Text = "Interval (secs)";
+ //
+ // comboBoxFilter
+ //
+ this.comboBoxFilter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.comboBoxFilter.FormattingEnabled = true;
+ this.comboBoxFilter.Location = new System.Drawing.Point(302, 5);
+ this.comboBoxFilter.Name = "comboBoxFilter";
+ this.comboBoxFilter.Size = new System.Drawing.Size(121, 21);
+ this.comboBoxFilter.TabIndex = 5;
+ this.comboBoxFilter.SelectedIndexChanged += new System.EventHandler(this.filter_changed);
+ this.comboBoxFilter.DropDownClosed += new System.EventHandler(this.mouse_Leave);
+ this.comboBoxFilter.DropDown += new System.EventHandler(this.mouse_Enter);
+ //
+ // panelControls
+ //
+ this.panelControls.Controls.Add(this.buttonExport);
+ this.panelControls.Controls.Add(this.buttonZero);
+ this.panelControls.Controls.Add(this.comboBoxInterval);
+ this.panelControls.Controls.Add(this.labelFilter);
+ this.panelControls.Controls.Add(this.comboBoxFilter);
+ this.panelControls.Controls.Add(this.labelInterval);
+ this.panelControls.Dock = System.Windows.Forms.DockStyle.Top;
+ this.panelControls.Location = new System.Drawing.Point(0, 110);
+ this.panelControls.Name = "panelControls";
+ this.panelControls.Size = new System.Drawing.Size(505, 32);
+ this.panelControls.TabIndex = 6;
+ //
+ // buttonExport
+ //
+ this.buttonExport.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.buttonExport.Location = new System.Drawing.Point(187, 4);
+ this.buttonExport.Name = "buttonExport";
+ this.buttonExport.Size = new System.Drawing.Size(75, 23);
+ this.buttonExport.TabIndex = 9;
+ this.buttonExport.Text = "Export";
+ this.buttonExport.UseVisualStyleBackColor = true;
+ this.buttonExport.Click += new System.EventHandler(this.buttonExport_Click);
+ //
+ // buttonZero
+ //
+ this.buttonZero.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.buttonZero.Location = new System.Drawing.Point(427, 4);
+ this.buttonZero.Name = "buttonZero";
+ this.buttonZero.Size = new System.Drawing.Size(75, 23);
+ this.buttonZero.TabIndex = 8;
+ this.buttonZero.Text = "Clear All";
+ this.buttonZero.UseVisualStyleBackColor = true;
+ this.buttonZero.Click += new System.EventHandler(this.buttonZero_Click);
+ //
+ // comboBoxInterval
+ //
+ this.comboBoxInterval.FormattingEnabled = true;
+ this.comboBoxInterval.Items.AddRange(new object[] {
+ "1",
+ "2",
+ "5",
+ "10",
+ "30",
+ "60"});
+ this.comboBoxInterval.Location = new System.Drawing.Point(84, 6);
+ this.comboBoxInterval.Name = "comboBoxInterval";
+ this.comboBoxInterval.Size = new System.Drawing.Size(55, 21);
+ this.comboBoxInterval.TabIndex = 7;
+ this.comboBoxInterval.Text = "1";
+ this.comboBoxInterval.SelectedIndexChanged += new System.EventHandler(this.interval_changed);
+ this.comboBoxInterval.DropDownClosed += new System.EventHandler(this.mouse_Leave);
+ this.comboBoxInterval.DropDown += new System.EventHandler(this.mouse_Enter);
+ //
+ // labelFilter
+ //
+ this.labelFilter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.labelFilter.AutoSize = true;
+ this.labelFilter.Location = new System.Drawing.Point(268, 9);
+ this.labelFilter.Name = "labelFilter";
+ this.labelFilter.Size = new System.Drawing.Size(29, 13);
+ this.labelFilter.TabIndex = 6;
+ this.labelFilter.Text = "Filter";
+ //
+ // saveFileDialogExport
+ //
+ this.saveFileDialogExport.FileName = "results.txt";
+ //
+ // menuStrip1
+ //
+ this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.fileToolStripMenuItem});
+ this.menuStrip1.Location = new System.Drawing.Point(0, 0);
+ this.menuStrip1.Name = "menuStrip1";
+ this.menuStrip1.Size = new System.Drawing.Size(505, 24);
+ this.menuStrip1.TabIndex = 7;
+ this.menuStrip1.Text = "menuStrip1";
+ //
+ // fileToolStripMenuItem
+ //
+ this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.openToolStripMenuItem,
+ this.closeToolStripMenuItem,
+ this.quitToolStripMenuItem});
+ this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
+ this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20);
+ this.fileToolStripMenuItem.Text = "File";
+ //
+ // openToolStripMenuItem
+ //
+ this.openToolStripMenuItem.Name = "openToolStripMenuItem";
+ this.openToolStripMenuItem.Size = new System.Drawing.Size(111, 22);
+ this.openToolStripMenuItem.Text = "Open";
+ this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click);
+ //
+ // closeToolStripMenuItem
+ //
+ this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
+ this.closeToolStripMenuItem.Size = new System.Drawing.Size(111, 22);
+ this.closeToolStripMenuItem.Text = "Close";
+ this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
+ //
+ // quitToolStripMenuItem
+ //
+ this.quitToolStripMenuItem.Name = "quitToolStripMenuItem";
+ this.quitToolStripMenuItem.Size = new System.Drawing.Size(111, 22);
+ this.quitToolStripMenuItem.Text = "Quit";
+ this.quitToolStripMenuItem.Click += new System.EventHandler(this.quitToolStripMenuItem_Click);
+ //
+ // listViewRates
+ //
+ this.listViewRates.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+ this.columnHeaderRateName,
+ this.columnHeaderRateCount,
+ this.columnHeaderRateTotaltime,
+ this.columnHeaderRateAvgTime});
+ this.listViewRates.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.listViewRates.FullRowSelect = true;
+ this.listViewRates.Location = new System.Drawing.Point(0, 0);
+ this.listViewRates.Name = "listViewRates";
+ this.listViewRates.Size = new System.Drawing.Size(505, 270);
+ this.listViewRates.Sorting = System.Windows.Forms.SortOrder.Descending;
+ this.listViewRates.TabIndex = 8;
+ this.listViewRates.UseCompatibleStateImageBehavior = false;
+ this.listViewRates.View = System.Windows.Forms.View.Details;
+ //
+ // columnHeaderRateName
+ //
+ this.columnHeaderRateName.Text = "Rate Name";
+ this.columnHeaderRateName.Width = 205;
+ //
+ // columnHeaderRateCount
+ //
+ this.columnHeaderRateCount.Text = "Count";
+ //
+ // columnHeaderRateTotaltime
+ //
+ this.columnHeaderRateTotaltime.Text = "Total Time (ms)";
+ this.columnHeaderRateTotaltime.Width = 100;
+ //
+ // columnHeaderRateAvgTime
+ //
+ this.columnHeaderRateAvgTime.Text = "Average Time (ms)";
+ this.columnHeaderRateAvgTime.Width = 110;
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.splitContainer1.Location = new System.Drawing.Point(0, 142);
+ this.splitContainer1.Name = "splitContainer1";
+ this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.Controls.Add(this.listViewCounters);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.Controls.Add(this.listViewRates);
+ this.splitContainer1.Size = new System.Drawing.Size(505, 495);
+ this.splitContainer1.SplitterDistance = 221;
+ this.splitContainer1.TabIndex = 9;
+ //
+ // StatsViewer
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(505, 637);
+ this.Controls.Add(this.splitContainer1);
+ this.Controls.Add(this.panelControls);
+ this.Controls.Add(this.panelHeader);
+ this.Controls.Add(this.menuStrip1);
+ this.DoubleBuffered = true;
+ this.Name = "StatsViewer";
+ this.Text = "Chrome Varz";
+ ((System.ComponentModel.ISupportInitialize)(this.pictureBoxTitle)).EndInit();
+ this.panelHeader.ResumeLayout(false);
+ this.panelHeader.PerformLayout();
+ this.panelControls.ResumeLayout(false);
+ this.panelControls.PerformLayout();
+ this.menuStrip1.ResumeLayout(false);
+ this.menuStrip1.PerformLayout();
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ this.splitContainer1.ResumeLayout(false);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ListView listViewCounters;
+ private System.Windows.Forms.ColumnHeader columnHeaderName;
+ private System.Windows.Forms.ColumnHeader columnHeaderValue;
+ private System.Windows.Forms.ColumnHeader columnHeaderDelta;
+ private System.Windows.Forms.PictureBox pictureBoxTitle;
+ private System.Windows.Forms.Panel panelHeader;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Label labelInterval;
+ private System.Windows.Forms.ComboBox comboBoxFilter;
+ private System.Windows.Forms.Panel panelControls;
+ private System.Windows.Forms.Label labelFilter;
+ private System.Windows.Forms.ComboBox comboBoxInterval;
+ private System.Windows.Forms.Label labelKills;
+ private System.Windows.Forms.Button buttonZero;
+ private System.Windows.Forms.Button buttonExport;
+ private System.Windows.Forms.SaveFileDialog saveFileDialogExport;
+ private System.Windows.Forms.MenuStrip menuStrip1;
+ private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem quitToolStripMenuItem;
+ private System.Windows.Forms.ListView listViewRates;
+ private System.Windows.Forms.ColumnHeader columnHeaderRateName;
+ private System.Windows.Forms.ColumnHeader columnHeaderRateCount;
+ private System.Windows.Forms.ColumnHeader columnHeaderRateTotaltime;
+ private System.Windows.Forms.ColumnHeader columnHeaderRateAvgTime;
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ }
+}
diff --git a/tools/stats_viewer/stats_viewer.cs b/tools/stats_viewer/stats_viewer.cs new file mode 100644 index 0000000..27fbda1 --- /dev/null +++ b/tools/stats_viewer/stats_viewer.cs @@ -0,0 +1,535 @@ +// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.IO;
+
+namespace StatsViewer {
+ public partial class StatsViewer : Form {
+ /// <summary>
+ /// Create a StatsViewer.
+ /// </summary>
+ public StatsViewer() {
+ InitializeComponent();
+ }
+
+ #region Protected Methods
+ /// <summary>
+ /// Callback when the form loads.
+ /// </summary>
+ /// <param name="e"></param>
+ protected override void OnLoad(EventArgs e) {
+ base.OnLoad(e);
+
+ timer_ = new Timer();
+ timer_.Interval = kPollInterval;
+ timer_.Tick += new EventHandler(PollTimerTicked);
+ timer_.Start();
+ }
+ #endregion
+
+ #region Private Methods
+ /// <summary>
+ /// Attempt to open the stats file.
+ /// Return true on success, false otherwise.
+ /// </summary>
+ private bool OpenStatsFile() {
+ StatsTable table = new StatsTable();
+ if (table.Open(kStatsTableName)) {
+ stats_table_ = table;
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Close the open stats file.
+ /// </summary>
+ private void CloseStatsFile() {
+ if (this.stats_table_ != null)
+ {
+ this.stats_table_.Close();
+ this.stats_table_ = null;
+ this.listViewCounters.Items.Clear();
+ }
+ }
+
+ /// <summary>
+ /// Updates the process list in the UI.
+ /// </summary>
+ private void UpdateProcessList() {
+ int current_pids = comboBoxFilter.Items.Count;
+ int table_pids = stats_table_.Processes.Count;
+ if (current_pids != table_pids + 1) // Add one because of the "all" entry.
+ {
+ int selected_index = this.comboBoxFilter.SelectedIndex;
+ this.comboBoxFilter.Items.Clear();
+ this.comboBoxFilter.Items.Add(kStringAllProcesses);
+ foreach (int pid in stats_table_.Processes)
+ this.comboBoxFilter.Items.Add(kStringProcess + pid.ToString());
+ this.comboBoxFilter.SelectedIndex = selected_index;
+ }
+ }
+
+ /// <summary>
+ /// Updates the UI for a counter.
+ /// </summary>
+ /// <param name="counter"></param>
+ private void UpdateCounter(IStatsCounter counter) {
+ ListView view;
+
+ // Figure out which list this counter goes into.
+ if (counter is StatsCounterRate)
+ view = listViewRates;
+ else if (counter is StatsCounter || counter is StatsTimer)
+ view = listViewCounters;
+ else
+ return; // Counter type not supported yet.
+
+ // See if the counter is already in the list.
+ ListViewItem item = view.Items[counter.name];
+ if (item != null)
+ {
+ // Update an existing counter.
+ Debug.Assert(item is StatsCounterListViewItem);
+ StatsCounterListViewItem counter_item = item as StatsCounterListViewItem;
+ counter_item.Update(counter, filter_pid_);
+ }
+ else
+ {
+ // Create a new counter
+ StatsCounterListViewItem new_item = null;
+ if (counter is StatsCounterRate)
+ new_item = new RateListViewItem(counter, filter_pid_);
+ else if (counter is StatsCounter || counter is StatsTimer)
+ new_item = new CounterListViewItem(counter, filter_pid_);
+ Debug.Assert(new_item != null);
+ view.Items.Add(new_item);
+ }
+ }
+
+ /// <summary>
+ /// Sample the data and update the UI
+ /// </summary>
+ private void SampleData() {
+ // If the table isn't open, try to open it again.
+ if (stats_table_ == null)
+ if (!OpenStatsFile())
+ return;
+
+ if (stats_counters_ == null)
+ stats_counters_ = stats_table_.Counters();
+
+ if (pause_updates_)
+ return;
+
+ stats_counters_.Update();
+
+ UpdateProcessList();
+
+ foreach (IStatsCounter counter in stats_counters_)
+ UpdateCounter(counter);
+ }
+
+ /// <summary>
+ /// Set the background color based on the value
+ /// </summary>
+ /// <param name="item"></param>
+ /// <param name="value"></param>
+ private void ColorItem(ListViewItem item, int value)
+ {
+ if (value < 0)
+ item.ForeColor = Color.Red;
+ else if (value > 0)
+ item.ForeColor = Color.DarkGreen;
+ else
+ item.ForeColor = Color.Black;
+ }
+
+ /// <summary>
+ /// Called when the timer fires.
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ void PollTimerTicked(object sender, EventArgs e) {
+ SampleData();
+ }
+
+ /// <summary>
+ /// Called when the interval is changed by the user.
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void interval_changed(object sender, EventArgs e) {
+ int interval = 1;
+ if (int.TryParse(comboBoxInterval.Text, out interval)) {
+ if (timer_ != null) {
+ timer_.Stop();
+ timer_.Interval = interval * 1000;
+ timer_.Start();
+ }
+ } else {
+ comboBoxInterval.Text = timer_.Interval.ToString();
+ }
+ }
+
+ /// <summary>
+ /// Called when the user changes the filter
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void filter_changed(object sender, EventArgs e) {
+ // While in this event handler, don't allow recursive events!
+ this.comboBoxFilter.SelectedIndexChanged -= new System.EventHandler(this.filter_changed);
+ if (this.comboBoxFilter.Text == kStringAllProcesses)
+ filter_pid_ = 0;
+ else
+ int.TryParse(comboBoxFilter.Text.Substring(kStringProcess.Length), out filter_pid_);
+ SampleData();
+ this.comboBoxFilter.SelectedIndexChanged += new System.EventHandler(this.filter_changed);
+ }
+
+ /// <summary>
+ /// Callback when the mouse enters a control
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void mouse_Enter(object sender, EventArgs e) {
+ // When the dropdown is expanded, we pause
+ // updates, as it messes with the UI.
+ pause_updates_ = true;
+ }
+
+ /// <summary>
+ /// Callback when the mouse leaves a control
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void mouse_Leave(object sender, EventArgs e) {
+ pause_updates_ = false;
+ }
+
+ /// <summary>
+ /// Called when the user clicks the zero-stats button.
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void buttonZero_Click(object sender, EventArgs e) {
+ this.stats_table_.Zero();
+ SampleData();
+ }
+
+ /// <summary>
+ /// Called when the user clicks a column heading.
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void column_Click(object sender, ColumnClickEventArgs e) {
+ if (e.Column != sort_column_) {
+ sort_column_ = e.Column;
+ this.listViewCounters.Sorting = SortOrder.Ascending;
+ } else {
+ if (this.listViewCounters.Sorting == SortOrder.Ascending)
+ this.listViewCounters.Sorting = SortOrder.Descending;
+ else
+ this.listViewCounters.Sorting = SortOrder.Ascending;
+ }
+
+ this.listViewCounters.ListViewItemSorter =
+ new ListViewItemComparer(e.Column, this.listViewCounters.Sorting);
+ this.listViewCounters.Sort();
+ }
+
+ /// <summary>
+ /// Called when the user clicks the button "Export".
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void buttonExport_Click(object sender, EventArgs e) {
+ //Have to pick a textfile to export to.
+ //Saves what is shown in listViewStats in the format: function value
+ //(with a tab in between), so that it is easy to copy paste into a spreadsheet.
+ //(Does not save the delta values.)
+ TextWriter tw = null;
+ try {
+ saveFileDialogExport.CheckFileExists = false;
+ saveFileDialogExport.ShowDialog();
+ tw = new StreamWriter(saveFileDialogExport.FileName);
+
+ for (int i = 0; i < listViewCounters.Items.Count; i++) {
+ tw.Write(listViewCounters.Items[i].SubItems[0].Text + "\t");
+ tw.WriteLine(listViewCounters.Items[i].SubItems[1].Text);
+ }
+ }
+ catch (IOException ex) {
+ MessageBox.Show(string.Format("There was an error while saving your results file. The results might not have been saved correctly.: {0}", ex.Message));
+ }
+ finally{
+ if (tw != null) tw.Close();
+ }
+ }
+
+ #endregion
+
+ class ListViewItemComparer : IComparer {
+ public ListViewItemComparer() {
+ this.col_ = 0;
+ this.order_ = SortOrder.Ascending;
+ }
+
+ public ListViewItemComparer(int column, SortOrder order) {
+ this.col_ = column;
+ this.order_ = order;
+ }
+
+ public int Compare(object x, object y) {
+ int return_value = -1;
+
+ object x_tag = ((ListViewItem)x).SubItems[col_].Tag;
+ object y_tag = ((ListViewItem)y).SubItems[col_].Tag;
+
+ if (Comparable(x_tag, y_tag))
+ return_value = ((IComparable)x_tag).CompareTo(y_tag);
+ else
+ return_value = String.Compare(((ListViewItem)x).SubItems[col_].Text,
+ ((ListViewItem)y).SubItems[col_].Text);
+
+ if (order_ == SortOrder.Descending)
+ return_value *= -1;
+
+ return return_value;
+ }
+
+ #region Private Methods
+ private bool Comparable(object x, object y) {
+ if (x == null || y == null)
+ return false;
+
+ return x is IComparable && y is IComparable;
+ }
+ #endregion
+
+ #region Private Members
+ private int col_;
+ private SortOrder order_;
+ #endregion
+ }
+
+ #region Private Members
+ private const string kStringAllProcesses = "All Processes";
+ private const string kStringProcess = "Process ";
+ private const int kPollInterval = 1000; // 1 second
+ private const string kStatsTableName = "ChromeStats";
+ private StatsTable stats_table_;
+ private StatsTableCounters stats_counters_;
+ private Timer timer_;
+ private int filter_pid_;
+ private bool pause_updates_;
+ private int sort_column_ = -1;
+ #endregion
+
+ #region Private Event Callbacks
+ private void openToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ OpenDialog dialog = new OpenDialog();
+ dialog.ShowDialog();
+
+ CloseStatsFile();
+
+ StatsTable table = new StatsTable();
+ bool rv = table.Open(dialog.FileName);
+ if (!rv)
+ {
+ MessageBox.Show("Could not open statsfile: " + dialog.FileName);
+ }
+ else
+ {
+ stats_table_ = table;
+ }
+ }
+
+ private void closeToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ CloseStatsFile();
+ }
+
+ private void quitToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ Application.Exit();
+ }
+ #endregion
+ }
+
+ /// <summary>
+ /// Base class for counter list view items.
+ /// </summary>
+ internal class StatsCounterListViewItem : ListViewItem
+ {
+ /// <summary>
+ /// Create the ListViewItem
+ /// </summary>
+ /// <param name="text"></param>
+ public StatsCounterListViewItem(string text) : base(text) { }
+
+ /// <summary>
+ /// Update the ListViewItem given a new counter value.
+ /// </summary>
+ /// <param name="counter"></param>
+ /// <param name="filter_pid"></param>
+ public virtual void Update(IStatsCounter counter, int filter_pid) { }
+
+ /// <summary>
+ /// Set the background color based on the value
+ /// </summary>
+ /// <param name="value"></param>
+ protected void ColorItem(int value)
+ {
+ if (value < 0)
+ ForeColor = Color.Red;
+ else if (value > 0)
+ ForeColor = Color.DarkGreen;
+ else
+ ForeColor = Color.Black;
+ }
+
+ /// <summary>
+ /// Create a new subitem with a zeroed Tag.
+ /// </summary>
+ /// <returns></returns>
+ protected ListViewSubItem NewSubItem()
+ {
+ ListViewSubItem item = new ListViewSubItem();
+ item.Tag = -1; // Arbitrarily initialize to -1.
+ return item;
+ }
+
+ /// <summary>
+ /// Set the value for a subitem.
+ /// </summary>
+ /// <param name="item"></param>
+ /// <param name="val"></param>
+ /// <returns>True if the value changed, false otherwise</returns>
+ protected bool SetSubItem(ListViewSubItem item, int val)
+ {
+ // The reason for doing this extra compare is because
+ // we introduce flicker if we unnecessarily update the
+ // subitems. The UI is much less likely to cause you
+ // a seizure when we do this.
+ if (val != (int)item.Tag)
+ {
+ item.Text = val.ToString();
+ item.Tag = val;
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// A listview item which contains a rate.
+ /// </summary>
+ internal class RateListViewItem : StatsCounterListViewItem
+ {
+ public RateListViewItem(IStatsCounter ctr, int filter_pid) :
+ base(ctr.name)
+ {
+ StatsCounterRate rate = ctr as StatsCounterRate;
+ Name = rate.name;
+ SubItems.Add(NewSubItem());
+ SubItems.Add(NewSubItem());
+ SubItems.Add(NewSubItem());
+ Update(ctr, filter_pid);
+ }
+
+ public override void Update(IStatsCounter counter, int filter_pid)
+ {
+ Debug.Assert(counter is StatsCounterRate);
+
+ StatsCounterRate new_rate = counter as StatsCounterRate;
+ int new_count = new_rate.GetCount(filter_pid);
+ int new_time = new_rate.GetTime(filter_pid);
+ int old_avg = Tag != null ? (int)Tag : 0;
+ int new_avg = new_count > 0 ? (new_time / new_count) : 0;
+ int delta = new_avg - old_avg;
+
+ SetSubItem(SubItems[column_count_index], new_count);
+ SetSubItem(SubItems[column_time_index], new_time);
+ if (SetSubItem(SubItems[column_avg_index], new_avg))
+ ColorItem(delta);
+ Tag = new_avg;
+ }
+
+ private const int column_count_index = 1;
+ private const int column_time_index = 2;
+ private const int column_avg_index = 3;
+ }
+
+ /// <summary>
+ /// A listview item which contains a counter.
+ /// </summary>
+ internal class CounterListViewItem : StatsCounterListViewItem
+ {
+ public CounterListViewItem(IStatsCounter ctr, int filter_pid) :
+ base(ctr.name)
+ {
+ Name = ctr.name;
+ SubItems.Add(NewSubItem());
+ SubItems.Add(NewSubItem());
+ Update(ctr, filter_pid);
+ }
+
+ public override void Update(IStatsCounter counter, int filter_pid) {
+ Debug.Assert(counter is StatsCounter || counter is StatsTimer);
+
+ int new_value = 0;
+ if (counter is StatsCounter)
+ new_value = ((StatsCounter)counter).GetValue(filter_pid);
+ else if (counter is StatsTimer)
+ new_value = ((StatsTimer)counter).GetValue(filter_pid);
+
+ int old_value = Tag != null ? (int)Tag : 0;
+ int delta = new_value - old_value;
+ SetSubItem(SubItems[column_value_index], new_value);
+ if (SetSubItem(SubItems[column_delta_index], delta))
+ ColorItem(delta);
+ Tag = new_value;
+ }
+
+ private const int column_value_index = 1;
+ private const int column_delta_index = 2;
+ }
+}
diff --git a/tools/stats_viewer/stats_viewer.csproj b/tools/stats_viewer/stats_viewer.csproj new file mode 100644 index 0000000..2b6fa6c --- /dev/null +++ b/tools/stats_viewer/stats_viewer.csproj @@ -0,0 +1,107 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{41735CD9-3E35-47F7-9FD1-4A9950B6B131}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>StatsViewer</RootNamespace>
+ <AssemblyName>stats_viewer</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>$(SolutionDir)$(Configuration)</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>$(SolutionDir)$(Configuration)</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Deployment" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="OpenDialog.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="OpenDialog.Designer.cs">
+ <DependentUpon>OpenDialog.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <Compile Include="stats_viewer.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="stats_viewer.Designer.cs">
+ <DependentUpon>stats_viewer.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <EmbeddedResource Include="OpenDialog.resx">
+ <SubType>Designer</SubType>
+ <DependentUpon>OpenDialog.cs</DependentUpon>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Resources.resx">
+ <SubType>Designer</SubType>
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <EmbeddedResource Include="stats_viewer.resx">
+ <SubType>Designer</SubType>
+ <DependentUpon>stats_viewer.cs</DependentUpon>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ <Compile Include="stats_table.cs" />
+ <Compile Include="win32.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Resources\kitten.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Resources\kittenbackground.png" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file diff --git a/tools/stats_viewer/stats_viewer.resx b/tools/stats_viewer/stats_viewer.resx new file mode 100644 index 0000000..117f389 --- /dev/null +++ b/tools/stats_viewer/stats_viewer.resx @@ -0,0 +1,1129 @@ +<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+ <data name="pictureBoxTitle.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>
+ iVBORw0KGgoAAAANSUhEUgAAAPgAAABWCAIAAABtpczCAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAAOxAAA
+ DsQBlSsOGwAA4PdJREFUeF5k/QVAXNf2/4GmdnutvZV4gjPu7oN70KBBEggJcScBgru7u7u7u2sggQTi
+ JLgmaa/1tnnrDGl///de++3umTMDDMPnfGfttdde81nzg+B3vz3/+edf9n3++W+f7fvss88+//zzfb99
+ /O3jr3C07+PHj8g5yR2f/fb5Z59JTnzc93Ef/PPZ55J/4d59+3777TfkzGdwz8fPP/8CTsMDkX8+R87v
+ g9OS7yF5DIzwGORbwQ+AB38BP0jyGPhayXeAx8AT2PspyH/wUyRPA77H3j/IwyR3Sb7hp/8kj5b8VHi4
+ 5CnDEdyUPAz53faeMzJ8hGe79+sgPwueC/JbID9xHzxbyZcgD5c8FeSLkV9Y8v0k5yRPDHk94IuQZ/L7
+ k/r03H5/Wnsvx96vtfddfn8FkG+GvFx7J+CZSJ6G5Bf6DXkCezf++CLJzb1fcu8l3btr74X69KrBr7f3
+ 6/8G3wN+H+R3/PRg+LWQ7yn5Q8Idn++9QvDCS37ZvdcE+Ta//iZ5QSS/oOQvgbzMkh8gOUBuw13Ic4Xv
+ uPc67/0PeSmQZ4P8ADiBfIu9v7Hkzr0fIXll954sPDP4ayLfU/JtADXJS4N829/gGcIvAH8deMrwf+Rb
+ 7n255IF7Z/aQkPxR4FXc+xGffl/kYb/uIbv35fCH3vfZF5/99uvHfakdJ2MGyQFteL9Ogm8nyb+bEtBL
+ Deym+HcTA3pIAd1k5EwPJbCHGtxHCRmkhgyQQwaIIQMkRIPk0CFK2DA1bIgiOaCEjyCKGKNHTjAixkH0
+ yEl61BSIGjFNi5qhg2IegWhxcyBqwiw1ZZ6ZscBOf8pJf8pKf8rMeM7KeM5Mf0FPe0ZLe05LfUZNXqCk
+ PqOlv2CkP2ekP6NlPKNmvKBmvqBmvaJlv6LnLIIYuYv03EVaziI1RzLmvqHkviXnviXlL5Hyl4mgvE83
+ KfnL5PwVcv4yKX+FULJOLt4gF6+TSzZoJZuM4i0acnODVLJJKtkil21RyjYpZRtUicifhJyhlK6Ty7eo
+ lds0UPUOtWaHujfW7tD+UN07Wu07hkT0PdW9p9f/xATBQcMOo36b0bjDaH7Han7PbHxHb3xPh7HhHa3h
+ HbXxPa3hPbXuHaVuV6J3lPr31IYPyMkGyV3I+IGGnJScb/qZ3vgTPIZY/wFf/wFb/wHXgIhQjwhuous/
+ YGrfYepA7/HIw96R6t6R63ZItdvEmm1i3TtS7S6hegdX+45Q+55QvYuv2sFVvsNX7hAqdwmVO8SKbVLF
+ NgXRFrVskwq/fskqsXiVhGiFXLwKrwmtZI0KByUrlOIVSukqtWSFWrRMLl6BA3rJMr1wiZq3TM1foecv
+ M/KXmHlvmXlv2Dmv2Vkv4C/OyHjBTH/KSF2gpy0wUhYYSXP0xFl6/ENK3Aw5bpoc+4AU84AYOYGPGMdG
+ TeAix0FYuBk+hgsZwoQM40KHCcFDhOBBfFA/IbCXENiHC+jDBvRi/bqxfl24gF6ibydhX3aPTXAL1r0S
+ 5VaDca3DuNZi79fjPOpw9+sw9+sxHg0Ej0aiRyPBswnv3ULwbsX7tOK8WzFeLYjgwKcN69eO92nD+bbj
+ /ToI/p1E/05CQDcpoIcMo38XXC3kwD5iUB8+cIAYNEgKHSKFj5BBEaPksCFC+DA+ZpwcP0GNm6AkTCGK
+ nSLFTBJiQVOE2GlC7ANi9CQ+ZgIXN0WMBU0S4idxCQ/widOIkmbwKY+IEhFSHuGTH+JSHkk0iwWlPsal
+ PcamPcakP4ERhMuYJ6Q/wafP49KeYDIWMNnPcVnPEGU/J2S/IGY9J2S9wGU+hfOY3Jf43JeEvJfE/Jek
+ /BfEvBf4vJcSvcDnvyLkwk04eEnIf4kvfIUreo0vfI2HsfgVvmRPrwkli4TiRbxEcEAofg0ilr4hl70l
+ ly6SS16R9lS+SC1/A6KUL5LL4d5FYvlbUsVbMowlyDfEgeCg9A2h7C2hdBFXuoj/fYQDfBnoDaFiiVD+
+ Fu5Cl75Blb5RLHuLKl9Cly9hyt5iyt6gy94iZ+A8cu8inMGCSt/gSl/DN8cUvcSUvMYWv0IVvFIsWkQX
+ vkYXvlIseKmQD2deo/NfofNeYnJfYHKf40A58Io9x8MrBq9exgI+Yx6fuUDIeorPfkbKfkbOWiBlzRMz
+ nxBgzHhMTHuMz3hCSn9CTp0jpsziUx6TUh9TUh9TU2apSbO0xIeMhGla3BQ1dpIaM0GLHCWHDxMjhknh
+ Q+TgPmJIPymoFx/QjduTfxfWp13Ru03Bt0MRDnzaFbzbFL1aFTya5T2aFT2aFD0a0e6NCLFuwG0dyr0O
+ eFZ0q1J0QcBGu1Zh9uX02oa24z1rMO71kscB3I0470a8ZyPWoxHr1UzwbiEB5V4I6DivFiyQ7d2G8W5D
+ +7Zj/DvhGcDzIAT2EGEEBfUR4ZIK6iUF91IQ9ZFD+smhg/DsEb4jJIoao0SNkSJHiDFjhPgJcuw4MWGK
+ nDRNTZgixU0SEmdICaBpQsJDYvwMPu4BHo4TZ4hJM6Skh6TkhyTAOn2WlDEHryAIXk1C6hw+ZRaBO3UO
+ yAbh058A0IQMeNEX4C8B7GIzFrAZ8wA6PuspIec5CcjOegZAY4H1nBf4nBcEEMCd9wqPUP4CU/CaACp8
+ RSx4RYKx6BUeEQD9+wgHCOKv/sAOOAN0sKWvsABQ2Wtc+Rt8+VtsxRts+Vt8xRsQoRyIBIiXyJVvyBWL
+ VFDlW3r1Eq16CRkr31Ar31CQB7whVL4lgsoXCeWLeBAcVy2RqpfJ1ctEUJVk/ENVS4TKJULVErFyCVvx
+ Fl25hNkbK5exlZInADd/F6b8DRzDGTiPA5W9xoDKF+E5IxdJGXJtoIvfoIpeK5bAmUVMySKu8DW24BW2
+ 4CU2H7ns4eKHF4qQ/RxeKEL2MyIIeT2fEbOekhDoF/BAeTYQ/5SUPk/InCenz5OTHxOS5wipQPwTaupj
+ WsocLekRNWGGnjBNj38AYsRNMqNGqQBJBAQFg8AMKbiPFNJHDgSvBN/sIvh3433a0d7tKJ92lHebvFer
+ PIDu2Yxyb5T3aEJ5NiOsArfuDXi3OpxrDcatGuNaiXatxLhUYO7XEl0r8fty+2zDOvFedRjPBuTR7o04
+ gNu3mejdDJTjfFqJXs14j0bwbzByrGczxrcd69eJCK6zwB5AHBFcgkG9YNvE0CEksAkeIIUOUCQihw3C
+ sydFjVKiEb4RgYXHjpMkfJMSp8gJk8SkaQCdnDBFiJvAA+iJj0iJDwlJswA6Lv4BBmw7aYaQAog/JKbM
+ EJIf4lMf4tJmcRlA8xw+bRabPodD9BhBGcjOWgC+4UVHXmvAOusp4tnAetZTbPYzfM5zct4rSu5LIvCN
+ OPQrQv4rIggx71fg1rh8+KO+hr8uYtIFr/AFL8G5cUUv0EUv0TAWvkAVvgRfxJW9QRAHDiQGKRkXJfQs
+ 4irf4Kvf4muWCDXLWERL+JplXN0ysQZgfUMEVb0hVb2lggDxulVG7Qq9eplWtUSpekupfEsG0CVCWN8T
+ UF61RK5ZIdWsEiUiwFiLiFS7BifhB+FrVgjVKzjguwr4BsqXsNUr+KolXOVbOAln9gQ3kbv2BPdKcEeu
+ h/I3mKoVXNUqvmIZW74Mro8qhysEfq+3WPD7olc45Ap/RYALO/8FIQ95iyPmviAVvKSC8p6TEWsHE4FX
+ Hv4EwPcCUfLmCXCTUh6Tk+dISWDqjyXHs5SkR5SEGQrYeTwCOlDOiB5jRo7QwgaBFiowE9JPCewmBnaT
+ A7pIvu0QLODAXr1a0J4t4OLA9ycjd29E3a8H1sGaEZt2q4cwBO9Wi3OrxrtVEO6V4p2LsbcL0a4VRJdy
+ 4r78AbuIbqJPA9a3Ge/djJO4OMQnYOQYwBoOfJCIBX4S8vMgPgHzDgLP7gHbxgf3AeIgfEg/IWyQiNj2
+ MGBNBsEb0J4kFk6OmaDGTlBiwb8nwLaJ8ZOkxGmwZ0rSDDnxAbg1OQk8exoOgGN4myOkPSalPZa83z3E
+ AtNpc3h4KwSlPsKlPsSmPpLADazP4jLnsJmPsZlPEGXN47Ln8dkL8E6KOE32U0LuM0Ie6Dkh5xkW3nbz
+ XkCwQSl4SUZ8+jWxAFCGkGORWLRIKgL/XgQLlwQhb/DFb/GlICRUwJYgAm9Dlb0GoUHli+CaYNVgkMAN
+ kISrAG7eYqvfSsYlXO0yoW4FX7eCrl1B1S6japYxcLN+lVC7BALiidUS1S6T61aptSuUmmVyzTIJVP2W
+ WP2WUA0O/RZfvYSvAoKXgWMQPBhfu0aoXSPWrQPfxD0B5bXrJDhTBwcr+Opl4BsHrMNYs4pHWF/GIZcB
+ IlzNiuTCQ87gqiWgS94K4A0Ewb0KuSDhJlwe+Oo3+MpFQpXkkoN3p+KX2OKXuJIX+JIXhKKXpMKX1MKX
+ tKKXjOJXrKKXrLyn1KwnpOwnxJwFcuY8CQwI/nZpc3t/RErqLC31ETXlERxQkKDlES3hIT1umh47SYsb
+ Z8SN0aNH6JEjjPAhKvAd0gdRAFBO9u8AL4eR7NuGBMwQSniB8wKTTWjAGuRWh3apRrnWIvG2cxXqXhXa
+ pRLjVkW4X0lwLcPfLcY7F+Ju56Nv5CneKcLcLcLvKxiyjeol+DVifMG/94ITCMTbEP8GAdlw81P83YUP
+ 6AIXxwHZiPpxoQP40AFC2BAR+IZoBBQxQoweB8+mIuY9ivh39DhQToqdBKAhBCclTBERsqdJqchvToY4
+ ZM+wkx9CkE1InSWmzhIgDoGABCIQiEPS5zCIVQPKEs/IeAKGAc5ByF4g5s6Tc+fhxSVkz2OzFzCAct5T
+ XC4Ct8RvnuOB8oIX5MKXYDxwgC98AX8wYjFExq/JJa+JEEMj8S6Eqm/wZcD0G0LJW4mQm7jyJVz5Mhbw
+ rUBiAAzic0hIgKl8g6l+C0JwAar+QAogQ0CUMFS7BP6Na1jFNayj69dQ9WvoulVs/Rq+YY0Iql8FkepW
+ ENWvkhvWKKC947pVcu0yqX55716wbUS1q3DBIKqHEb52jdSwToJxT7UrBDjZACdXCXAhwcNqJV8FAtYl
+ uMPJvasOB08DeSYwrsCliNsDHd4ogHUIruBaqlsh1rxFVPuWXPOWUg1vL29J8MoUvoIgHignFj8nFb2g
+ FL1mlLxhFb9i5z9n5D1nwFjwggljzgIta4EGQXnaHIiS8ZiW8YSRNktPfQis09Me0mFMesiIf8iMfcCM
+ mWDGjjJiRxjRw/SIIXpoPzUIpnPdJEiEBHRS/Tsofu1U/3aabxvFq5mIBM/NIIIkwJaEKLU4l2qwcIJL
+ Le5OJfZOOfZeGe5+BdmtjHi3AHcrFwu6k4+9U4C7mYe6mqW4r3DILroX79eA8mnCeDfvzS//j/IAyMN0
+ EiAhgwTivbjAXmxgLyaoDxPcjw0dxIcPw2ySGDFCiBwFvkkQk0SNEWPgYIIMN4H76AlyzCQpbooUP00G
+ C0fi7BkiePZeqA1Yg3nDJFLCNzF1Dt7siMj73Rzu92gbmwFWPf9JWQtYCAFznoE9IzTnv6DkQYD4FJ/z
+ FKZKGAgw8p7j8yA4gXvh7RX4RsJrECH/Ba7wBRbmiGUwHUREKH0N0zjEkmGWVraIhvfuqhVC1Rqxco0I
+ iAPflcu4yhVkBBqqIR5YkTC9jK0FLUmEAI0YZO0qrm4N3BovQZkAONav4OpXsAA6IF6/pli3CiMcI/cC
+ c3A9wAhY71HeuA6gwzECOsL6CqkBoEe4J9aBea+RYES+5yqhYQ/o/xNyEx4GF0/jBtAP3xNXt4KgXLuG
+ q13/XXCdAOur8G6Aq13F1Kyia1ZAmOrlvfci8G8ChPu1qxAakashOgLQ3xBrl8hVSzCFoJQvUUqXyMib
+ 3hty8WsKUF4I3vGaVvKWWbTIArjzXzDznjH2lPuMmf2UlfGEnv6Ymj5Hz3zCyHjCTJtlpj1kpjwCMZJh
+ AjrDiHvAiJ6gR48zIodpgHj4IFBOgxkdBCoBncA3xb+DCnx7t1C8m6ieTRSPRtL9eoJbHZImAb5da3D3
+ qjDOFWjnCuzdCtzNMsz1YtTNYsytQrRzEe5eMf52Pv5mNv5mDgh3Ixt3LRt9KR0B3TaqBy9xdKwEdCwk
+ T8DCfTvAv5F5QCAyy8QH9eLAwoP70cH9qNBBdOggJnwYGzGKjxzFRY7hosZx0RP46EkCkiGZxEcjNyFz
+ QkLyJFP4eJhZQmQi8ey99IgkMYLfAxq0N3dE8iGI4CY2/QmkSjAZ85gsyI08xUmEBSERCIIycib3OQJ0
+ 7jNczjNMznN0/kts3gsITrCQEoEQvOA1Gf42EJAgs6hnqKLnMOVC3oglMzwcTL8k0zJU2Vv58jcKlcvo
+ qlV09Rq2Zg1cEMJcdDWcWcIA4ojeoqqR8ANVs6QI0Uj9CkYioBkBq34N07CObVhDnBLgbgSt4WFsWMPU
+ rQLlChC9wAMa1+E8Yrp7yDauI8bcuEZCDiQ2j9wEre7pE9O/P4wIX9u0ToARrpY9waW1d9C0RmzeBNbh
+ R8AzwTRuYOpXUXXwTrKBrV/H1K1h9qCvWcPUrMHviJIcYKtXkSAeYn2gHEy9bo1SAxEUaIlS85YMXi6Z
+ GVMrlully1TklVykFr2iQcRS+JKS/5Kc/4KW95Ke94KZ+4yV+5SV+5wNB9kLrMwn7IzHADct5SE1BTFy
+ ZspDVso0K3mGlfSQlTDDigMvn6RHjlIjhmlhQ7SQfmpILy24hwYu7ttG9muj+bZSvZop3ohoHvUUd0RU
+ 1xqCcwXmbiUIB+Z9sxh1owh1vRB9tQB1vRhztRB9OVfxSrbitRzU9Sz0jSzcrRzi9Sz8lXTM5TTU5Qz0
+ 5XTMvsJh29gBUmArHlLpvhCIQ0K9g4AkCiFQgbRON04Si+NC+nEhA5iQQcXQIcWwYVTEKDpiFBMFec1x
+ GBFFT2Bjp3CxU9iYSWzMBCbuASH+ASFuCpcwjUucgSkmLvkRZi8x8in3NwfHIAyMvyMO6SokPQIJPkme
+ BJ25gMp+is59DgTjc18g6S04Bklw38MaDy6OJL9eYPJewjxyTxB5kwoXScVvSUVIXg9b/AJV8hJdsYhk
+ P6reIuEvRNKVS6iqZUVQ5ZI8omWF6hXFmlVU7aoksF5ByK5Fgmx07ZJi7YoCUFu/gmpcQTetYprXME2r
+ 2EYIA1YQyiWQIZw1rmGa17EtG/iWDVzTOqZpHQ1qXMO2bOJbNolN6ySAEgR8N20galxHiEcE5+HeDVIz
+ CO5FHkluWqc0bZDh3qZ1YvMGoWWD0LwOWOOb1/BNq3g4aFpHxuY1uAvftIFp2kA3rqP34qWGdeQaq1tT
+ rF9HS0CXUA52voauWUeuZ8klDaAjoQuwXgkTg2UI/Wm1a/TqFZgZw1yZXvWWUblEL12kFL4kFr2kFL+k
+ Fz+nF72g578CxEGMvBec3GecnAU2KHuelfmYnfmYmzHHSXvETJ6hJ88wUmaAcnbyA07SNDdxmhf3gBMz
+ yYoeZ0YgU09aWD89pJce0EUP6KAD4j6tVJ8Wuk8Lw6Oe6tFA9Wpk3K+lu9XQXaupzuWEWyXY26U4GG8U
+ Ya4XYq4VYK7kKl7IVrxagLuci3bKVLicibqShbmSgbqagb6WibmUqngpReEiKE3BKUV+X/GIXfwQOagN
+ F9iG9+/AI5lvMHIkYwjhOFZi5PgQiMUHscEDqNAhhdBhhbBhBSA7cgwNY8wkIA4jNvYBpAKxcVOo+Ck0
+ KOEBVpLnxiXP4JIeYhNnUEkPFVNmMZL0H5LVTp1D/57hRvLcv+cBMVnPIOUHggNU9nP07xADx9g9gXlL
+ sMb+jvUffOMKIBH2GkYcZEsKJZnskje4kjeY0tcYyWQL0hcwBUSmepJZI6pqSbF6WaHqrXzlW/maFVTd
+ KgrxQuTNHQ7QDYgw9YiRy1cvy9SvKjSto5pXFFvXMO0buNZ1YBpMGtgCwjDNm0AzrmUT27aFb93Ete1p
+ C9+2CTcJbVvE1g1iyzqhZY2IaJ3cuiXRJqKWTRIIUAa1bpLaNkitG5SWDXLzOqV5A0RGvhAunnX4oYja
+ Nwjt64S2dXzbOg4ZN/Dtm4SWTXgOmJYtbDOCO0wMgHIFGBs20HXr2Dqw9k+CwAaZqsKkYi80ql2lAOhI
+ ngden1Vq1Qq1cpla/ZZW84ZZvcgof00tfkGWiFr6gl7ynFH0glkAE9BnzLyn7LynPFDOPCf7CSfrMRsQ
+ z5jjp8ywk6clLv6AlTjJTpzgJoxzY8e4MeO8mDFO9Cg7eoQVMcQM62cEddMDu1iBnayADpZvKxMQ92pk
+ ejYw3esYrtU0lyqqSxX9bjnjdin5egH2ah7qWgEWUT72Si72Ujb6QibKKQN1MQtzPhN9Hg7SFC+moi6n
+ oa+koy6lyjslyZxPlAVdSJU/nyyzr2jENm4QH9CCDmjHBiJzTcioECGpgqwt9WACesHFCaHDxJAhWIVC
+ h42gwsfAzhWjxlCRYygJ4ujoKVTsA0zcNDYGKH+gmPAAnTgNOUFcChKrwCIONvEhOvkROmUWlToH+oNv
+ dPo8Gll3mEfWbiRGjpXktveEzgGf/p3mPcT3yP6Dckkme08wW0IEee4iWKB5gytCEn/IsghMJSExXPoW
+ VQGh9gqEoZSqZTKoGtILMJtcgT85GolbVsDwMODiQHkdBLJwAKwvo+uWUaDaZfmaVan6NdnGdYWmVbmW
+ NVQbWPWqYhP4t8RHAfSWDTByRK1bgB2+YxPftU3o2CJ0bBKBSxiRg01S+8YntW0SgM52OLlNbNsiwE1E
+ W8jDQG2b5LYNSusmrWWT2roJB3AG37GB21PnJr5zU3L8x8lNuKLgp8PTQHBHnhJY+5oiEA8RVMM6vmEd
+ ZsaIGjdw9es4JOxBgiUygF6zCuE4JPgJFfDKrFArliiwblX5llb1hlHxmlb6iloMXv4KQnNK4XNq0TNa
+ ISD+jJO7wM1d4Oc9FeYtCHOe8EHZT3hg56kPuUnA9xQzaZKVOMGOH+PGjfDiRvjRw4LIIV54PzuslxnW
+ Sw/toYd2MwPbmf5tLL92tm8r27uJ5dXIcq9jutcy3aoZd8upd8oot0upN4to1wtIV/Nwl3PAwhHEr+Ti
+ LmRizqejHFMVz6bIO6YpOqQqOCTLOybJn0uUO58ofyEZKJc9lyB9Nk7aIUbqXKLs2XhpCF1s4oYIga2Y
+ gDbMJ9AhI46so2ID+zBB/VhYWQ0dIoQNE8JGcOEQkU9ARA5ejihmCowcRnTcNA5Aj55UiH+gAOYNcEsC
+ cXwyZAPnYJESghY0QvljRVDaExSQvUe5JETZAx0sHBZuYJESsXPEy19iQX8gvnewRzkCPbKqRyhBRIT1
+ xeKXsMpIhFxK6SIBMtxlr5GsdjkSgsOioGL5MrpiBV+5SqoEx1qmwvtyDdgYhKeQgFvFISO8j69BvgJJ
+ wNVCQLKOBxeEGAYicjB1IKZ2DUCXalyTbViVbVlTaN1EIdCvoVoRvP5PretYBMQtAqhrm9i5BSJJ2CV1
+ bZM7QVsgCjIisOK74GF7ktxEwN0EwwbBOwC1bYvWtklt26R0IBcAAnfnJlYyfhJ8IfJVG9iOLRw8k+Z1
+ 9B7ryLNCrB3TtAnEQwSFxPf/j5DYCea7tSBJgrIKEi/L5MoVsHZaxRK1DFh/Sy97Qy9ZpBW/pUAQWLhI
+ zn9FzX1BzQM9YwLiufOC3CfC3CeinMfCrFl+1iwva5aTMQuxODPxATNhihE/wYob48QMc2OGBDFD4qhB
+ cXi/MKKHF9bFCumgB4PamQEtTJ8mpk8zx7uJ49nA8mxg30coZ7pUMu+U0m4WUa7nk67mEq/mEq7mES5l
+ Y4H1i9mYCxmYcymKDklyoNMJMqeTZO0SZc4kyDgkyJyNlzkbJ+OISNohVto+WtY+WsYhVvZMtPS+omGb
+ eCgV6MQHdmBhoTUQmXdKcuT92BBAfBApIUAOgPURHDL7HIdJJzZ6Ah09CXxj46Yxv9s5OmpSIWFaMfkh
+ BviG1XhkQX4WUoRIljD1MQQtKED8/x90YH1PMIPMf02C5UkAHew8X5Lk3tOekYMgtQLZbmTZ8iXkCiWg
+ I4gjKgMh6+cgWLKR5M6WYfVbofSNfDlkCVeIVTDTWmXWrbBr37LqV1h1y3TIoMHaTfVbUu0SBVS/RKlb
+ JtcvExtWyY1rZJgRQijcDHHwJrZxU6ZpU6YZtCHXsqnQto1u2UQ1b6CQ4EQSn0hCFBx4+R7lEhG7NkGk
+ TqB8i9S9Te7eQg6Q4y1S7xZxTz1/aJPQs0XoRi4P+FpS+xa1Y4vWvgmigPfDBdC5iekGbWH31LOF7d3G
+ 92zhujfRnRuY9i2IlHDt2/B8cIiv7wnimQ0gHkL8T5JE/zDZJTesQDYTWW9CTH2NVAHRC2RaVmgVK7Ty
+ ZWrxG0rRIhnh+y05Z5GQ84qY85qS84qWAxPQBXb+nFLBnFLeQ3HujChnRpg1zc+a5mbNcDOmOckPICLn
+ Jk5y4sbY4OVRA9zIfkFkn1J4ryi8RxDeww/tZAe10YJa6UEtTP9mllcd06eR59XIvV/DvF/DcqlkOJfR
+ 7pTQbhSQr+QQL2cTLsGcModwOQcHUYpTOupcqoJjsvzZZHn7BDn7BPnT8bK2CTK2cdK2sVKn46TsY6XO
+ REudiTxmF3HMJvyYbZiUXYTs6Sh52wjZfYUjVnEj2BAEcUxAD9YfwpUeTFAvNqgPEizYkAEcpBGhKCV0
+ EBc6hGRaosYJUZNg6sA6zDhxSGg+BeE41J9g4qdQiTMQnaOTZrAgSeUJHlk4gOVfZHEeyaWkPUZL0imS
+ ueZTcHEwdWQEIwc7z4MVylewRI/MPoteE4tfwzoOTCgheQJL8TigHPiG4BsJwSFd+BJX+pJYArHjS2r5
+ a1LlK1wlrGYjC+8I4rWQD1km1L4hVy9S616zml4K2p6Lu1+odS5odcxpdsxqtk+rtU2pto4rt4wptU0o
+ tY+Lu8ZEnQ9E3XMqPfOqfaCnot5XvK4lZhuE1JuYtm1U67Z867ZM67Zsx65i+za2cxt8mgLO3QWOu0Vs
+ g9AZiNwm7glCl27QFhEZt/F7Y88OAdS7S+jfJQzsEPq3CX2fROzbJvbsEHt2ST3bFFD3Nq1ri9aDjHBt
+ wPsDrnsbBw/uBW3he7eRxw/skvp34GrBd2/CvciPg+8AY9s6FiYSrWt4ZGIAQiJ4eItAZgItm5TmdTLM
+ dBvXKPWwVgWzz1UK+HoVsrRErl6lA+UlS5RiJJkIaURy/htqLrjPC1LeAqPwibB4RrVsUqdyxKhi2LB0
+ WL94SLdoSLdgULtoWLtoSCtnUDN1QD21XyOlTzWpWzmhWymmSxTZJYroVgrtEYaAuoWB7Vz/FqZ3I9W3
+ kerXzPauY3nV89xreeDi9yoYt4qpEKhcyyNfziZdSCc6pRHPp+LPpWIdU9AOyQpnkxXsE+XOJMrZJyqe
+ SVCwjZW1i5a2jZGxjZK2jjhuHX7MJuKoTcQx2/CjdqFHbEOO2IBCj9lGSJ0KObqvaPRU7DAmpAsd2IOB
+ cCWgF+3fgwroQQX2ooL7P+XLJSlzKLiBZCIe8oaRE0iyJWYSB6mVOMgeTuEkoAPuGBDgvsf6XvQCC0Bp
+ c8g62e95Q2y6JCgHC98LxyWTTrBwJGiRVJsgNSeQ+QbDBhWCkOBbsmaJ1JkggTgsXkKpUxnkwl/B0g+9
+ +BWt7DVBspQDGXHEuSEfXL9EbX7Nbnkuan6i2jKt0T6m09Gv09mp096k21yr1Vip2VSq2Vyi1VSk2VSg
+ 3lKk0Vyk3lKo1lyq0lGv1d2s292s1duu0T+k1jut1LXA71pkdq/SumAKuKHQtiXXtgMjqmOH1L1D3iOs
+ e5uEOPE2oXOX2P2OhGiX2LtLAiH4ItpDHE4iGkREGtwhDe2QJAfk/h1y3w4ZAR1GhHUqqHcHRrLk+8CX
+ 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
+ /wd6M4989rNkxAAAAABJRU5ErkJggg==
+</value>
+ </data>
+ <data name="panelHeader.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>
+ 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
+ SUVORK5CYII=
+</value>
+ </data>
+ <metadata name="saveFileDialogExport.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>17, 17</value>
+ </metadata>
+ <metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>171, 17</value>
+ </metadata>
+</root>
\ No newline at end of file diff --git a/tools/stats_viewer/win32.cs b/tools/stats_viewer/win32.cs new file mode 100644 index 0000000..f09afa48 --- /dev/null +++ b/tools/stats_viewer/win32.cs @@ -0,0 +1,75 @@ +// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace StatsViewer {
+ /// <summary>
+ /// Win32 API constants, structs, and wrappers for access via C#.
+ /// </summary>
+ class Win32 {
+ #region Constants
+ public enum MapAccess {
+ FILE_MAP_COPY = 0x0001,
+ FILE_MAP_WRITE = 0x0002,
+ FILE_MAP_READ = 0x0004,
+ FILE_MAP_ALL_ACCESS = 0x001f,
+ }
+
+ public const int GENERIC_READ = unchecked((int)0x80000000);
+ public const int GENERIC_WRITE = unchecked((int)0x40000000);
+ public const int OPEN_ALWAYS = 4;
+ public static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
+ #endregion
+
+ [DllImport("kernel32", SetLastError=true, CharSet=CharSet.Auto)]
+ public static extern IntPtr CreateFile (
+ String lpFileName, int dwDesiredAccess, int dwShareMode,
+ IntPtr lpSecurityAttributes, int dwCreationDisposition,
+ int dwFlagsAndAttributes, IntPtr hTemplateFile);
+
+ [DllImport("kernel32", SetLastError=true)]
+ public static extern IntPtr MapViewOfFile (
+ IntPtr hFileMappingObject, int dwDesiredAccess, int dwFileOffsetHigh,
+ int dwFileOffsetLow, int dwNumBytesToMap);
+
+ [DllImport("kernel32", SetLastError=true, CharSet=CharSet.Auto)]
+ public static extern IntPtr OpenFileMapping (
+ int dwDesiredAccess, bool bInheritHandle, String lpName);
+
+ [DllImport("kernel32", SetLastError=true)]
+ public static extern bool UnmapViewOfFile (IntPtr lpBaseAddress);
+
+ [DllImport("kernel32", SetLastError = true)]
+ public static extern bool CloseHandle(IntPtr handle);
+ }
+}
|