├── .gitignore ├── BinaryFileInspectorGUI ├── BfsErrorHandler.cs ├── BinaryFileInspectorGUI.csproj ├── Inspector.Designer.cs ├── Inspector.cs ├── Inspector.resx ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings └── Resources │ ├── page_gear.png │ └── page_go.png ├── BinaryFileSchema.FxCop ├── BinaryFileSchema.sln ├── BinaryFileSchema ├── AstConvert.cs ├── AstNodes.cs ├── BfsCompiler.cs ├── BinaryFileSchema.csproj ├── BinaryFileSchemaParser.cs ├── CodeGenerators │ └── CSharp │ │ ├── BfsBinaryReader.cs │ │ ├── CSharpGenerator.cs │ │ └── CSharpHelperFunctions.cs ├── ErrorHandling.cs ├── Phases │ ├── DefiniteAssignment.cs │ ├── Environments.cs │ ├── HelperClasses.cs │ ├── Hierarchy.cs │ ├── TypeChecking.cs │ └── TypeLinking.cs └── Properties │ └── AssemblyInfo.cs ├── BinaryFileSchemaGUI ├── BFSGUI.Designer.cs ├── BFSGUI.cs ├── BFSGUI.resx ├── BinaryFileSchemaGUI.csproj ├── CodeOutput.Designer.cs ├── CodeOutput.cs ├── CodeOutput.resx ├── FastRichEdit.cs ├── ListBoxErrorHandler.cs ├── ListViewErrorHandler.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Resources │ ├── cog_go.png │ ├── control_play_blue.png │ ├── disk.png │ ├── disk1.png │ ├── folder.png │ ├── help.png │ └── page.png ├── SchemaColorizer.cs ├── binary.ico └── binary_large.ico ├── CommandLineGenerator ├── CommandLineGenerator.csproj ├── Program.cs └── Properties │ └── AssemblyInfo.cs ├── Fsg.peg ├── PegBase ├── PEG Base.csproj ├── PegBase.cs ├── Properties │ ├── AssemblyInfo.cs │ └── vssver2.scc └── vssver2.scc ├── Phases.txt ├── README.txt └── TestFileGenerator ├── Program.cs ├── Properties └── AssemblyInfo.cs └── TestFileGenerator.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | #OS junk files 2 | [Tt]humbs.db 3 | *.DS_Store 4 | 5 | #Visual Studio files 6 | *.[Oo]bj 7 | *.user 8 | *.aps 9 | *.pch 10 | *.vspscc 11 | *.vssscc 12 | *_i.c 13 | *_p.c 14 | *.ncb 15 | *.suo 16 | *.tlb 17 | *.tlh 18 | *.bak 19 | *.[Cc]ache 20 | *.ilk 21 | *.log 22 | *.lib 23 | *.sbr 24 | *.sdf 25 | *.opensdf 26 | *.unsuccessfulbuild 27 | ipch/ 28 | obj/ 29 | [Bb]in 30 | [Dd]ebug*/ 31 | [Rr]elease*/ 32 | Ankh.NoLoad 33 | 34 | #Tooling 35 | _ReSharper*/ 36 | *.resharper 37 | [Tt]est[Rr]esult* 38 | 39 | #Project files 40 | [Bb]uild/ 41 | 42 | #Subversion files 43 | .svn 44 | 45 | # Office Temp Files 46 | ~$* 47 | 48 | #NuGet 49 | packages/ 50 | 51 | #ncrunch 52 | *ncrunch* 53 | *crunch*.local.xml -------------------------------------------------------------------------------- /BinaryFileInspectorGUI/BfsErrorHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows.Forms; 6 | using BFSchema; 7 | 8 | namespace BinaryFileInspectorGUI 9 | { 10 | class BfsErrorHandler : IBfsErrorHandler 11 | { 12 | ListView list; 13 | 14 | public BfsErrorHandler(ListView listview) 15 | { 16 | list = listview; 17 | } 18 | 19 | public void HandleError(SourceError error) 20 | { 21 | list.Items.Add(new ListViewItem(error.Message)); 22 | } 23 | 24 | public void HandleWarning(SourceError error) 25 | { 26 | list.Items.Add(new ListViewItem(error.Message)); 27 | } 28 | 29 | public void HandleMessage(SourceError error) 30 | { 31 | list.Items.Add(new ListViewItem(error.Message)); 32 | } 33 | 34 | public void HandleMessage(string message) 35 | { 36 | list.Items.Add(new ListViewItem(message)); 37 | } 38 | 39 | public void HandleError(string message) 40 | { 41 | list.Items.Add(new ListViewItem(message)); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /BinaryFileInspectorGUI/BinaryFileInspectorGUI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {BE8E0D41-8057-4F42-B4AD-EB992531EC98} 9 | WinExe 10 | Properties 11 | BinaryFileInspectorGUI 12 | BinaryFileInspectorGUI 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 3.5 37 | 38 | 39 | 3.5 40 | 41 | 42 | 3.5 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | Form 54 | 55 | 56 | Inspector.cs 57 | 58 | 59 | 60 | 61 | Inspector.cs 62 | Designer 63 | 64 | 65 | ResXFileCodeGenerator 66 | Resources.Designer.cs 67 | Designer 68 | 69 | 70 | True 71 | Resources.resx 72 | True 73 | 74 | 75 | SettingsSingleFileGenerator 76 | Settings.Designer.cs 77 | 78 | 79 | True 80 | Settings.settings 81 | True 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | {B99A0149-B187-4075-AD79-A36A084BF73A} 93 | BinaryFileSchema 94 | 95 | 96 | 97 | 104 | -------------------------------------------------------------------------------- /BinaryFileInspectorGUI/Inspector.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace BinaryFileInspectorGUI 2 | { 3 | partial class Inspector 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.toolStrip1 = new System.Windows.Forms.ToolStrip(); 32 | this.toolButtonLoadSchema = new System.Windows.Forms.ToolStripButton(); 33 | this.toolButtonLoadFile = new System.Windows.Forms.ToolStripButton(); 34 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 35 | this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); 36 | this.treeView1 = new System.Windows.Forms.TreeView(); 37 | this.splitContainer1 = new System.Windows.Forms.SplitContainer(); 38 | this.listView1 = new System.Windows.Forms.ListView(); 39 | this.toolStrip1.SuspendLayout(); 40 | this.statusStrip1.SuspendLayout(); 41 | this.splitContainer1.Panel1.SuspendLayout(); 42 | this.splitContainer1.Panel2.SuspendLayout(); 43 | this.splitContainer1.SuspendLayout(); 44 | this.SuspendLayout(); 45 | // 46 | // toolStrip1 47 | // 48 | this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 49 | this.toolButtonLoadSchema, 50 | this.toolButtonLoadFile}); 51 | this.toolStrip1.Location = new System.Drawing.Point(0, 0); 52 | this.toolStrip1.Name = "toolStrip1"; 53 | this.toolStrip1.Size = new System.Drawing.Size(606, 25); 54 | this.toolStrip1.TabIndex = 0; 55 | this.toolStrip1.Text = "toolStrip1"; 56 | // 57 | // toolButtonLoadSchema 58 | // 59 | this.toolButtonLoadSchema.Image = global::BinaryFileInspectorGUI.Properties.Resources.page_gear; 60 | this.toolButtonLoadSchema.ImageTransparentColor = System.Drawing.Color.Magenta; 61 | this.toolButtonLoadSchema.Name = "toolButtonLoadSchema"; 62 | this.toolButtonLoadSchema.Size = new System.Drawing.Size(97, 22); 63 | this.toolButtonLoadSchema.Text = "Load schema"; 64 | // 65 | // toolButtonLoadFile 66 | // 67 | this.toolButtonLoadFile.Image = global::BinaryFileInspectorGUI.Properties.Resources.page_go; 68 | this.toolButtonLoadFile.ImageTransparentColor = System.Drawing.Color.Magenta; 69 | this.toolButtonLoadFile.Name = "toolButtonLoadFile"; 70 | this.toolButtonLoadFile.Size = new System.Drawing.Size(72, 22); 71 | this.toolButtonLoadFile.Text = "Load file"; 72 | // 73 | // statusStrip1 74 | // 75 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 76 | this.toolStripStatusLabel1}); 77 | this.statusStrip1.Location = new System.Drawing.Point(0, 420); 78 | this.statusStrip1.Name = "statusStrip1"; 79 | this.statusStrip1.Size = new System.Drawing.Size(606, 22); 80 | this.statusStrip1.TabIndex = 1; 81 | this.statusStrip1.Text = "statusStrip1"; 82 | // 83 | // toolStripStatusLabel1 84 | // 85 | this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; 86 | this.toolStripStatusLabel1.Size = new System.Drawing.Size(231, 17); 87 | this.toolStripStatusLabel1.Text = "Binary File Inspector - By Anders Riggelsen"; 88 | // 89 | // treeView1 90 | // 91 | this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill; 92 | this.treeView1.Location = new System.Drawing.Point(0, 0); 93 | this.treeView1.Name = "treeView1"; 94 | this.treeView1.Size = new System.Drawing.Size(606, 325); 95 | this.treeView1.TabIndex = 2; 96 | // 97 | // splitContainer1 98 | // 99 | this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; 100 | this.splitContainer1.Location = new System.Drawing.Point(0, 25); 101 | this.splitContainer1.Name = "splitContainer1"; 102 | this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; 103 | // 104 | // splitContainer1.Panel1 105 | // 106 | this.splitContainer1.Panel1.Controls.Add(this.treeView1); 107 | // 108 | // splitContainer1.Panel2 109 | // 110 | this.splitContainer1.Panel2.Controls.Add(this.listView1); 111 | this.splitContainer1.Size = new System.Drawing.Size(606, 395); 112 | this.splitContainer1.SplitterDistance = 325; 113 | this.splitContainer1.TabIndex = 3; 114 | // 115 | // listView1 116 | // 117 | this.listView1.Dock = System.Windows.Forms.DockStyle.Fill; 118 | this.listView1.Location = new System.Drawing.Point(0, 0); 119 | this.listView1.Name = "listView1"; 120 | this.listView1.Size = new System.Drawing.Size(606, 66); 121 | this.listView1.TabIndex = 0; 122 | this.listView1.UseCompatibleStateImageBehavior = false; 123 | this.listView1.View = System.Windows.Forms.View.Details; 124 | // 125 | // Form1 126 | // 127 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 128 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 129 | this.ClientSize = new System.Drawing.Size(606, 442); 130 | this.Controls.Add(this.splitContainer1); 131 | this.Controls.Add(this.statusStrip1); 132 | this.Controls.Add(this.toolStrip1); 133 | this.Name = "Form1"; 134 | this.Text = "Binary File Inspector"; 135 | this.Load += new System.EventHandler(this.Form1_Load); 136 | this.toolStrip1.ResumeLayout(false); 137 | this.toolStrip1.PerformLayout(); 138 | this.statusStrip1.ResumeLayout(false); 139 | this.statusStrip1.PerformLayout(); 140 | this.splitContainer1.Panel1.ResumeLayout(false); 141 | this.splitContainer1.Panel2.ResumeLayout(false); 142 | this.splitContainer1.ResumeLayout(false); 143 | this.ResumeLayout(false); 144 | this.PerformLayout(); 145 | 146 | } 147 | 148 | #endregion 149 | 150 | private System.Windows.Forms.ToolStrip toolStrip1; 151 | private System.Windows.Forms.ToolStripButton toolButtonLoadSchema; 152 | private System.Windows.Forms.ToolStripButton toolButtonLoadFile; 153 | private System.Windows.Forms.StatusStrip statusStrip1; 154 | private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; 155 | private System.Windows.Forms.TreeView treeView1; 156 | private System.Windows.Forms.SplitContainer splitContainer1; 157 | private System.Windows.Forms.ListView listView1; 158 | } 159 | } 160 | 161 | -------------------------------------------------------------------------------- /BinaryFileInspectorGUI/Inspector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Text; 7 | using System.Windows.Forms; 8 | using System.IO; 9 | using BFSchema; 10 | 11 | namespace BinaryFileInspectorGUI 12 | { 13 | public partial class Inspector : Form 14 | { 15 | BinaryFileSchema schema; 16 | BfsBinaryReader reader; 17 | 18 | public Inspector() 19 | { 20 | InitializeComponent(); 21 | } 22 | 23 | private void Form1_Load(object sender, EventArgs e) 24 | { 25 | OpenSchema(@"C:\Users\Anders\Desktop\Binary File Schema\photoshop.fsc"); 26 | OpenFile(@"C:\Users\Anders\Desktop\Binary File Schema\128x512x4.psd"); 27 | } 28 | 29 | public void OpenSchema(string filename) 30 | { 31 | BfsErrorHandler errorHandler = new BfsErrorHandler(listView1); 32 | toolStripStatusLabel1.Text = "Opening schema: " + filename; 33 | schema = new BinaryFileSchema(filename, errorHandler); 34 | } 35 | 36 | public void OpenFile(string filename) 37 | { 38 | BinaryReader b_reader = new BinaryReader(new FileStream(filename, FileMode.Open)); 39 | 40 | BfsBinaryReader.Endianness endianness; 41 | if(schema.ByteOrder.ByteOrder == BfsByteOrderEnum.BigEndian) 42 | endianness = BfsBinaryReader.Endianness.BigEndian; 43 | else 44 | endianness = BfsBinaryReader.Endianness.LittleEndian; 45 | 46 | reader = new BfsBinaryReader(b_reader, endianness); 47 | TreeNode rootNode = new TreeNode(schema.FormatBlock.Name); 48 | treeView1.Nodes.Add(rootNode); 49 | ReadDataBlock(schema.FormatBlock, rootNode); 50 | rootNode.ExpandAll(); 51 | } 52 | 53 | private void ReadDataBlock(IBfsDataBlock block, TreeNode parent) 54 | { 55 | if (block is BfsStruct) 56 | ReadStruct(block as BfsStruct, parent); 57 | else if (block is BfsEnum) 58 | ReadEnum(block as BfsEnum, parent); 59 | else if (block is BfsBitfield) 60 | ReadBitField(block as BfsBitfield, parent); 61 | } 62 | 63 | private void AddFileLine(string data, IBfsType type, TreeNode parent) 64 | { 65 | TreeNode node = new TreeNode(data); 66 | node.Tag = type; 67 | parent.Nodes.Add(node); 68 | } 69 | 70 | private void ReadStruct(BfsStruct bfsstruct, TreeNode parent) 71 | { 72 | foreach(BfsStructField field in bfsstruct.StructFieldList) 73 | { 74 | TreeNode nodeParent = parent; 75 | if (field.FieldType.ArrayExtension is BfsKnownArray) 76 | { 77 | BfsKnownArray knownArray = field.FieldType.ArrayExtension as BfsKnownArray; 78 | TreeNode arrayParent = new TreeNode(field.Name + " []"); 79 | parent.Nodes.Add(arrayParent); 80 | //TODO: Evaluate expression and use that number for the loop 81 | //for(int i = 0; i 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 122, 17 125 | 126 | -------------------------------------------------------------------------------- /BinaryFileInspectorGUI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | namespace BinaryFileInspectorGUI 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// The main entry point for the application. 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | Application.Run(new Inspector()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /BinaryFileInspectorGUI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("BinaryFileInspectorGUI")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("BinaryFileInspectorGUI")] 13 | [assembly: AssemblyCopyright("Copyright © 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("eb380db6-8e4f-4c1f-90b1-a3584e0a2e36")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /BinaryFileInspectorGUI/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:2.0.50727.4200 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace BinaryFileInspectorGUI.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BinaryFileInspectorGUI.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | internal static System.Drawing.Bitmap page_gear { 64 | get { 65 | object obj = ResourceManager.GetObject("page_gear", resourceCulture); 66 | return ((System.Drawing.Bitmap)(obj)); 67 | } 68 | } 69 | 70 | internal static System.Drawing.Bitmap page_go { 71 | get { 72 | object obj = ResourceManager.GetObject("page_go", resourceCulture); 73 | return ((System.Drawing.Bitmap)(obj)); 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /BinaryFileInspectorGUI/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\page_gear.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Resources\page_go.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | -------------------------------------------------------------------------------- /BinaryFileInspectorGUI/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:2.0.50727.4200 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace BinaryFileInspectorGUI.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /BinaryFileInspectorGUI/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BinaryFileInspectorGUI/Resources/page_gear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/BinaryFileInspectorGUI/Resources/page_gear.png -------------------------------------------------------------------------------- /BinaryFileInspectorGUI/Resources/page_go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/BinaryFileInspectorGUI/Resources/page_go.png -------------------------------------------------------------------------------- /BinaryFileSchema.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BinaryFileSchema", "BinaryFileSchema\BinaryFileSchema.csproj", "{B99A0149-B187-4075-AD79-A36A084BF73A}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BinaryFileSchemaGUI", "BinaryFileSchemaGUI\BinaryFileSchemaGUI.csproj", "{0FBAE211-1E37-4CE8-AE39-59E67D78F4A8}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PEG Base", "PegBase\PEG Base.csproj", "{9913580D-1543-40D5-B463-14C95BF3120C}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BinaryFileInspectorGUI", "BinaryFileInspectorGUI\BinaryFileInspectorGUI.csproj", "{BE8E0D41-8057-4F42-B4AD-EB992531EC98}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandLineGenerator", "CommandLineGenerator\CommandLineGenerator.csproj", "{B569D745-AAB4-47CB-AAF7-80351C36E31D}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestFileGenerator", "TestFileGenerator\TestFileGenerator.csproj", "{6ADA732D-754B-41B7-8C87-033153BBF6B1}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Any CPU = Debug|Any CPU 19 | Release|Any CPU = Release|Any CPU 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {B99A0149-B187-4075-AD79-A36A084BF73A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {B99A0149-B187-4075-AD79-A36A084BF73A}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {B99A0149-B187-4075-AD79-A36A084BF73A}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {B99A0149-B187-4075-AD79-A36A084BF73A}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {0FBAE211-1E37-4CE8-AE39-59E67D78F4A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {0FBAE211-1E37-4CE8-AE39-59E67D78F4A8}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {0FBAE211-1E37-4CE8-AE39-59E67D78F4A8}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {0FBAE211-1E37-4CE8-AE39-59E67D78F4A8}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {9913580D-1543-40D5-B463-14C95BF3120C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {9913580D-1543-40D5-B463-14C95BF3120C}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {9913580D-1543-40D5-B463-14C95BF3120C}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {9913580D-1543-40D5-B463-14C95BF3120C}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {BE8E0D41-8057-4F42-B4AD-EB992531EC98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {BE8E0D41-8057-4F42-B4AD-EB992531EC98}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {BE8E0D41-8057-4F42-B4AD-EB992531EC98}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {BE8E0D41-8057-4F42-B4AD-EB992531EC98}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {B569D745-AAB4-47CB-AAF7-80351C36E31D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {B569D745-AAB4-47CB-AAF7-80351C36E31D}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {B569D745-AAB4-47CB-AAF7-80351C36E31D}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {B569D745-AAB4-47CB-AAF7-80351C36E31D}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {6ADA732D-754B-41B7-8C87-033153BBF6B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {6ADA732D-754B-41B7-8C87-033153BBF6B1}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {6ADA732D-754B-41B7-8C87-033153BBF6B1}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {6ADA732D-754B-41B7-8C87-033153BBF6B1}.Release|Any CPU.Build.0 = Release|Any CPU 46 | EndGlobalSection 47 | GlobalSection(SolutionProperties) = preSolution 48 | HideSolutionNode = FALSE 49 | EndGlobalSection 50 | EndGlobal 51 | -------------------------------------------------------------------------------- /BinaryFileSchema/BfsCompiler.cs: -------------------------------------------------------------------------------- 1 | using Peg.Base; 2 | 3 | namespace BFSchema 4 | { 5 | public sealed class BfsCompiler 6 | { 7 | static bool gotError; 8 | static IBfsErrorHandler handler; 9 | 10 | public static BinaryFileSchema CheckBfs(BinaryFileSchema schema, IBfsErrorHandler errorHandler) 11 | { 12 | handler = errorHandler; 13 | 14 | IPhase[] phases = new IPhase[] { 15 | new Environments(), 16 | new TypeLinking(), 17 | new Hierarchy(), 18 | new TypeChecking(), 19 | new DefiniteAssignment() 20 | }; 21 | 22 | gotError = false; 23 | 24 | foreach (IPhase phase in phases) 25 | { 26 | phase.Check(schema); 27 | 28 | if (gotError && errorHandler != null) 29 | { 30 | errorHandler.HandleMessage("Schema has errors. Compilation stopped."); 31 | return null; 32 | } 33 | } 34 | 35 | return schema; 36 | } 37 | 38 | public static BinaryFileSchema ParseBfs(string source, IBfsErrorHandler errorHandler) 39 | { 40 | return ParseBfs(new BinaryFileSchema(), source, errorHandler); 41 | } 42 | 43 | public static BinaryFileSchema ParseBfs(BinaryFileSchema schema, string source, IBfsErrorHandler errorHandler) 44 | { 45 | gotError = false; 46 | handler = errorHandler; 47 | BinaryFileSchemaParser.BinaryFileSchemaParser parser = new BinaryFileSchemaParser.BinaryFileSchemaParser(); 48 | parser.Construct(source, new StreamErrorHandler(errorHandler) ); 49 | bool matches = false; 50 | try 51 | { 52 | matches = parser.bfschema(); 53 | } 54 | catch (PegException ex) 55 | { 56 | errorHandler.HandleMessage(ex.Message); 57 | } 58 | 59 | if (!matches) 60 | { 61 | ReportMessage("Schema didn't parse."); 62 | return null; 63 | } 64 | 65 | AstConvert converter = new AstConvert(schema,source); 66 | schema = converter.GetBFSTree(parser.GetRoot()); 67 | schema = CheckBfs(schema,errorHandler); 68 | 69 | return schema; 70 | } 71 | 72 | public static void ReportMessage(string message) 73 | { 74 | if (handler != null) 75 | handler.HandleMessage(message); 76 | } 77 | 78 | public static void ReportError( BfsSourceRange range, string message ) 79 | { 80 | gotError = true; 81 | if (handler != null) 82 | handler.HandleError(new SourceError(range, "Error: " + message)); 83 | } 84 | public static void ReportError(string message) 85 | { 86 | gotError = true; 87 | if (handler != null) 88 | handler.HandleError(new SourceError(new BfsSourceRange(), "Error: " + message)); 89 | } 90 | 91 | public static void ReportWarning( BfsSourceRange range, string message ) 92 | { 93 | if (handler != null) 94 | handler.HandleWarning(new SourceError(range, "Warning: " + message)); 95 | } 96 | public static void ReportWarning(string message) 97 | { 98 | if (handler != null) 99 | handler.HandleWarning(new SourceError(new BfsSourceRange(), "Warning: " + message)); 100 | } 101 | 102 | private BfsCompiler() { } 103 | } 104 | 105 | public interface IPhase 106 | { 107 | void Check(BinaryFileSchema schema); 108 | } 109 | 110 | public interface CodeGenerator 111 | { 112 | string GenerateCode(BinaryFileSchema schema); 113 | } 114 | 115 | 116 | } 117 | -------------------------------------------------------------------------------- /BinaryFileSchema/BinaryFileSchema.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {B99A0149-B187-4075-AD79-A36A084BF73A} 9 | Library 10 | Properties 11 | BFSchema 12 | BinaryFileSchema 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 3.5 37 | 38 | 39 | 40 | 3.5 41 | 42 | 43 | 3.5 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | PreserveNewest 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | {9913580D-1543-40D5-B463-14C95BF3120C} 70 | PEG Base 71 | 72 | 73 | 74 | 81 | -------------------------------------------------------------------------------- /BinaryFileSchema/CodeGenerators/CSharp/BfsBinaryReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | using System.Net; 5 | using System.IO.Compression; 6 | 7 | //namespace BfsHelperClasses 8 | //{ 9 | 10 | public class BfsBinaryReader 11 | { 12 | BinaryReader reader; 13 | ASCIIEncoding asciienc; 14 | UTF7Encoding utf7enc; 15 | UTF32Encoding utf32enc; 16 | 17 | public long Position { get { return GetPosition(); } set { Seek(value, SeekOrigin.Begin); } } 18 | public long Length { get { return reader.BaseStream.Length; } } 19 | 20 | public Stream BaseStream { get { return reader.BaseStream; } } 21 | 22 | public enum Endianness { LittleEndian, BigEndian } 23 | 24 | public BfsBinaryReader(BinaryReader binaryReader, Endianness fileEndianness) 25 | { 26 | reader = binaryReader; 27 | FileEndianness = fileEndianness; 28 | asciienc = new ASCIIEncoding(); 29 | utf7enc = new UTF7Encoding(); 30 | utf32enc = new UTF32Encoding(); 31 | } 32 | 33 | public Endianness FileEndianness { get; set; } 34 | 35 | public void TestReadCompressed() 36 | { 37 | GZipStream gstream = new GZipStream(reader.BaseStream, CompressionMode.Decompress); 38 | Console.WriteLine("Can seek: " + gstream.CanSeek.ToString() ); 39 | } 40 | 41 | public void SkipBytes(int count) 42 | { 43 | reader.BaseStream.Seek(count, SeekOrigin.Current); 44 | } 45 | 46 | public byte[] ReadByteArray(int count) 47 | { 48 | return reader.ReadBytes(count); 49 | } 50 | 51 | public bool ReadBool() 52 | { 53 | return reader.ReadBoolean(); 54 | } 55 | 56 | public byte ReadUbyte() 57 | { 58 | return reader.ReadByte(); 59 | } 60 | 61 | public byte ReadSbyte() 62 | { 63 | return (byte)reader.ReadSByte(); 64 | } 65 | 66 | public short ReadShort() 67 | { 68 | if (FileEndianness == Endianness.BigEndian) 69 | return IPAddress.HostToNetworkOrder(reader.ReadInt16()); 70 | else 71 | return reader.ReadInt16(); 72 | } 73 | 74 | public short ReadUshort() 75 | { 76 | if (FileEndianness == Endianness.BigEndian) 77 | return IPAddress.HostToNetworkOrder(reader.ReadInt16()); 78 | else 79 | return (short)reader.ReadUInt16(); 80 | } 81 | 82 | public int ReadInt() 83 | { 84 | if (FileEndianness == Endianness.BigEndian) 85 | return IPAddress.HostToNetworkOrder(reader.ReadInt32()); 86 | else 87 | return reader.ReadInt32(); 88 | } 89 | 90 | public int ReadUint() 91 | { 92 | if (FileEndianness == Endianness.BigEndian) 93 | return (int)IPAddress.HostToNetworkOrder(reader.ReadInt32()); 94 | else 95 | return (int)reader.ReadUInt32(); 96 | } 97 | 98 | public long ReadLong() 99 | { 100 | if (FileEndianness == Endianness.BigEndian) 101 | return IPAddress.HostToNetworkOrder(reader.ReadInt32()); 102 | else 103 | return reader.ReadInt32(); 104 | } 105 | 106 | //returning long instead of ulong to be CLS compliant. (might fail because of the same range+conversion) 107 | public long ReadUlong() 108 | { 109 | if (FileEndianness == Endianness.BigEndian) 110 | return (long)IPAddress.HostToNetworkOrder(reader.ReadInt64()); 111 | else 112 | return (long)reader.ReadUInt64(); 113 | } 114 | 115 | public string ReadASCIIString(string expected) 116 | { 117 | byte[] tmp_string = reader.ReadBytes(expected.Length); 118 | string text = asciienc.GetString(tmp_string); 119 | if (text != expected) 120 | throw new FormatException("Error reading ASCII string! Expected: " + expected + ", got: " + text); 121 | return text; 122 | } 123 | 124 | public string ReadUTF7String(string expected) 125 | { 126 | byte[] tmp_string = reader.ReadBytes(expected.Length); 127 | string text = utf7enc.GetString(tmp_string); 128 | if (text != expected) 129 | throw new FormatException("Error reading UTF7 string! Expected: " + expected + ", got: " + text); 130 | return text; 131 | } 132 | 133 | public string ReadUTF32String(string expected) 134 | { 135 | byte[] tmp_string = reader.ReadBytes(expected.Length * 4); 136 | string text = utf32enc.GetString(tmp_string); 137 | if (text != expected) 138 | throw new FormatException("Error reading UTF32 string! Expected: " + expected + ", got: " + text); 139 | return text; 140 | } 141 | 142 | public long GetPosition() 143 | { 144 | return reader.BaseStream.Position; 145 | } 146 | 147 | public long Seek(long offset, SeekOrigin origin) 148 | { 149 | return reader.BaseStream.Seek(offset, origin); 150 | } 151 | } 152 | 153 | public class StopCaseTester 154 | { 155 | StopCase [] stopcases; 156 | BfsBinaryReader file; 157 | int stoppedAtCase = 0; 158 | int stopcasesLeft; 159 | bool stopsAtEOF; 160 | 161 | public StopCaseTester( BfsBinaryReader file, bool stopsAtEOF, StopCase [] stopcases ) 162 | { 163 | this.stopcases = stopcases; 164 | this.file = file; 165 | this.stopsAtEOF = stopsAtEOF; 166 | stoppedAtCase = 0; 167 | } 168 | 169 | public bool CanContinue() 170 | { 171 | long seek = file.Position; 172 | stopcasesLeft = stopcases.Length; 173 | bool[] dead = new bool[stopcases.Length]; 174 | int index = 0; 175 | 176 | while (stopcasesLeft > 0) 177 | { 178 | if (stopsAtEOF && file.BaseStream.Position == file.BaseStream.Length) 179 | return false; 180 | 181 | byte b = file.ReadUbyte(); 182 | for (int i = 0; i < stopcases.Length; i++) 183 | { 184 | if (dead[i] == false) 185 | { 186 | if (stopcases[i].stopcase[index] != b) 187 | { 188 | dead[i] = true; 189 | stopcasesLeft--; 190 | } 191 | 192 | if (index == stopcases[i].stopcase.Length - 1 && dead[i] == false) 193 | { 194 | stoppedAtCase = i; 195 | file.Position = seek; 196 | return false; 197 | } 198 | } 199 | } 200 | index++; 201 | } 202 | file.Position = seek; 203 | return true; 204 | } 205 | 206 | public StopCase StoppedAtCase() 207 | { 208 | return stopcases[stoppedAtCase]; 209 | } 210 | } 211 | 212 | public struct StopCase 213 | { 214 | public byte[] stopcase; 215 | public bool isIncluded; 216 | public bool isSkipped; 217 | public int matches; 218 | public StopCase(byte [] stopcase, bool included, bool skipped) 219 | { 220 | this.stopcase = stopcase; 221 | this.isIncluded = included; 222 | this.isSkipped = skipped; 223 | matches = 0; 224 | } 225 | } 226 | 227 | public class CircularBuffer 228 | { 229 | int size; 230 | int position; 231 | int bufferUsage; 232 | byte[] buffer; 233 | 234 | public CircularBuffer(int size) 235 | { 236 | this.size = size; 237 | buffer = new byte[size]; 238 | position = 0; 239 | bufferUsage = 0; 240 | } 241 | 242 | public void ReadByte(byte b) 243 | { 244 | buffer[position] = b; 245 | position = (position + 1) % size; 246 | bufferUsage = Math.Max(bufferUsage + 1, size); 247 | } 248 | 249 | public void ReadBytes(byte [] bytes) 250 | { 251 | for (int i = 0; i < bytes.Length; i++) 252 | ReadByte(bytes[i]); 253 | } 254 | 255 | public bool BufferMatches(string text) 256 | { 257 | char[] chars = text.ToCharArray(); 258 | byte[] bytes = new byte[chars.Length]; 259 | for (int i = 0; i < chars.Length; i++) 260 | bytes[i] = (byte)chars[i]; 261 | return BufferMatches(bytes); 262 | } 263 | 264 | public bool BufferMatches(byte[] bytes) 265 | { 266 | if (bufferUsage < bytes.Length) 267 | return false; 268 | 269 | for (int i = 0; i < bytes.Length; i++) 270 | { 271 | int u = (position + i) % size; 272 | if (buffer[u] != bytes[i]) 273 | return false; 274 | } 275 | return true; 276 | } 277 | 278 | } 279 | 280 | //} -------------------------------------------------------------------------------- /BinaryFileSchema/CodeGenerators/CSharp/CSharpHelperFunctions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | 4 | namespace BFSchema.CodeGenerators.CSharp 5 | { 6 | public class CSHelper 7 | { 8 | public static string TypeMap(IBfsType type) 9 | { 10 | if (type is BfsNamedType) 11 | return (type as BfsNamedType).DataBlock.Name; 12 | 13 | if (type is BfsPrimitiveType) 14 | { 15 | string typeString = (type as BfsPrimitiveType).PrimitiveType.ToString(); 16 | switch (typeString) 17 | { 18 | case "Ubyte": 19 | return "Byte"; 20 | case "Sbyte": 21 | return "Byte"; 22 | default: 23 | return typeString; 24 | } 25 | } 26 | else return "/* TODO!!! */"; 27 | } 28 | 29 | public static string ReadMap(BfsPrimitiveType primitiveType) 30 | { 31 | switch (primitiveType.PrimitiveType.ToString()) 32 | { 33 | case "Ubyte": 34 | return "Byte"; 35 | case "Sbyte": 36 | return "SByte"; 37 | case "Short": 38 | return "Int16"; 39 | case "Ushort": 40 | return "UInt16"; 41 | case "Int": 42 | return "Int32"; 43 | case "Uint": 44 | return "UInt32"; 45 | case "Long": 46 | return "Int64"; 47 | case "Ulong": 48 | return "UInt64"; 49 | default: 50 | return primitiveType.PrimitiveType.ToString(); 51 | } 52 | } 53 | 54 | //Output C# code for an expression 55 | public static string MakeExpression(BfsExpression expression, IBfsDataBlock owner) 56 | { 57 | string exp = VisitExpGroup(expression.ExpressionGroup, owner); 58 | 59 | //Trim unnessecary parenthesis (BROKEN! not sure the parenthethis are matching) 60 | /*while (exp.StartsWith("(") && exp.EndsWith(")")) 61 | exp = exp.Substring(1, exp.Length - 2);*/ 62 | 63 | return exp.Trim(); 64 | } 65 | 66 | //Recursive visit of expression groups 67 | public static string VisitExpGroup(BfsExpGroup group, IBfsDataBlock owner) 68 | { 69 | StringBuilder b = new StringBuilder(); 70 | b.Append("("); 71 | 72 | for (int i = 0; i < group.Members.Count; i++) 73 | { 74 | IBfsExpNode node = group.Members[i]; 75 | 76 | if (node is BfsExpGroup) 77 | b.Append(VisitExpGroup(node as BfsExpGroup, owner)); 78 | else if (node is BfsExpressionVariable) 79 | { 80 | BfsExpressionVariable expVar = node as BfsExpressionVariable; 81 | b.Append(owner.Name.ToLower()); 82 | 83 | foreach (IBfsNamedField namedField in expVar.NameHierarchy) 84 | b.Append("." + namedField.Name); 85 | 86 | //Only append this last reading into the enum type if the value is being compared against an EnumAliasExp 87 | if ((group.Members.Count > i + 2 && group.Members[i + 2] is BfsEnumAliasExp) 88 | || (i >= 2 && group.Members[i - 2] is BfsEnumAliasExp)) 89 | b.Append("." + expVar.NameHierarchy[expVar.NameHierarchy.Count - 1]); 90 | } 91 | else if (node is BfsEnumAliasExp) 92 | { 93 | //TODO 94 | BfsEnumAliasExp enumAliasExp = node as BfsEnumAliasExp; 95 | b.Append(enumAliasExp.EnumBlock.Name + "." + enumAliasExp.EnumBlock.Name + "Enum." + enumAliasExp.Alias.Name); 96 | } 97 | else if (node is BfsLocalField) 98 | { 99 | BfsLocalField localField = node as BfsLocalField; 100 | b.Append(localField.Name); 101 | } 102 | else 103 | b.Append(" " + node + " "); 104 | } 105 | b.Append(")"); 106 | return b.ToString(); 107 | } 108 | 109 | } 110 | 111 | 112 | 113 | public class CodeClass 114 | { 115 | public enum ClassTypeEnum { Class, Struct } 116 | public CodeClass(string name) { Name = name; ClassType = ClassTypeEnum.Class; } 117 | public string Name { get; set; } 118 | public List CodeMethods { get { return codeMethods; } } 119 | public List CodeFields { get { return codeFields; } } 120 | public ClassTypeEnum ClassType { get; set; } 121 | 122 | List codeMethods = new List(); 123 | List codeFields = new List(); 124 | 125 | 126 | public override string ToString() 127 | { 128 | StringBuilder b = new StringBuilder(); 129 | b.AppendLine("\tpublic " + ClassType.ToString().ToLower() + " " + Name); 130 | b.AppendLine("\t{"); 131 | 132 | foreach (string line in codeFields) 133 | b.AppendLine("\t\tpublic " + line); 134 | b.AppendLine(); 135 | 136 | foreach (CodeMethod cm in codeMethods) 137 | b.AppendLine(cm.ToString()); 138 | 139 | b.AppendLine("\t}"); 140 | b.AppendLine(); 141 | return b.ToString(); 142 | } 143 | } 144 | 145 | public class CodeMethod 146 | { 147 | public CodeMethod(string name) { Name = name; } 148 | public string Name { get; set; } 149 | public List CodeLines { get { return codeLines; } } 150 | List codeLines = new List(); 151 | 152 | public void AddSplitLines(string lines) 153 | { 154 | string [] lineArray = lines.Split(new char[] { '\n', '\r'}); 155 | foreach (string str in lineArray) 156 | if (str.Trim() != string.Empty) 157 | codeLines.Add(str); 158 | } 159 | 160 | public override string ToString() 161 | { 162 | StringBuilder b = new StringBuilder(); 163 | 164 | string staticString = (Name.StartsWith("override")) ? "" : "static "; 165 | 166 | b.AppendLine("\t\tpublic " + staticString + Name); 167 | b.AppendLine("\t\t{"); 168 | 169 | foreach (string cl in codeLines) 170 | b.AppendLine("\t\t\t" + cl); 171 | 172 | b.AppendLine("\t\t}"); 173 | return b.ToString(); 174 | } 175 | } 176 | 177 | 178 | public class IfThenElseSequence 179 | { 180 | public List IfBlocks { get { return ifBlocks; } } 181 | List ifBlocks = new List(); 182 | public IfBlock ElseBlock { get; set; } 183 | public string Indent { get; set; } 184 | public string ErrorValue { get; set; } 185 | 186 | public IfThenElseSequence(string indent, string errorValue) 187 | { 188 | Indent = indent; 189 | ErrorValue = errorValue; 190 | Indent = string.Empty; 191 | ElseBlock = new IfBlock(""); 192 | if(errorValue != null && errorValue != string.Empty) 193 | ElseBlock.CodeLines.Add("throw new Exception(\"Enum did not match! "+ errorValue +"'.\");"); 194 | else 195 | ElseBlock.CodeLines.Add("throw new Exception(\"Enum did not match!\");"); 196 | } 197 | 198 | public override string ToString() 199 | { 200 | StringBuilder b = new StringBuilder(); 201 | List tmp_ifblocks = new List(ifBlocks); 202 | 203 | //Makes a list over the empty clauses to put them last (merged) 204 | List emptyIfBlocks = new List(); 205 | foreach (IfBlock ifblock in ifBlocks) 206 | if (ifblock.CodeLines.Count == 0) 207 | emptyIfBlocks.Add(ifblock); 208 | //Deletes them from the other list and compresses them into the else-clause 209 | ElseBlock.Sentence = string.Empty; 210 | 211 | for( int i = 0; i CodeLines { get { return codeLines; } } 247 | List codeLines = new List(); 248 | public string Indent { get; set; } 249 | 250 | public IfBlock() 251 | { 252 | Indent = string.Empty; 253 | } 254 | 255 | public override string ToString() 256 | { 257 | StringBuilder b = new StringBuilder(); 258 | 259 | if (Sentence != null && Sentence != string.Empty) 260 | b.AppendLine(Indent + "if( " + Sentence + " )"); 261 | 262 | if (codeLines.Count > 1) 263 | b.AppendLine(Indent + "{"); 264 | 265 | foreach(string codeLine in codeLines) 266 | b.AppendLine(Indent + " \t" + codeLine); 267 | 268 | if (codeLines.Count > 1) 269 | b.AppendLine(Indent + "}"); 270 | return b.ToString(); 271 | } 272 | } 273 | 274 | } 275 | -------------------------------------------------------------------------------- /BinaryFileSchema/ErrorHandling.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | using System.Windows.Forms; 7 | using BFSchema; 8 | using System.Globalization; 9 | 10 | namespace BFSchema 11 | { 12 | public interface IBfsErrorHandler 13 | { 14 | void HandleMessage(string message); 15 | void HandleError(string message); 16 | void HandleError(SourceError errorMessage); 17 | void HandleWarning(SourceError warningMessage); 18 | } 19 | 20 | public class SourceError 21 | { 22 | public string Message { get; set; } 23 | public BfsSourceRange SourceRange { get; set; } 24 | 25 | public SourceError(BfsSourceRange range, string message ) 26 | { 27 | Message = message; 28 | SourceRange = range; 29 | } 30 | 31 | public override string ToString() 32 | { 33 | return Message; 34 | } 35 | } 36 | 37 | public class StreamErrorHandler : TextWriter 38 | { 39 | IBfsErrorHandler errorhandler; 40 | 41 | public StreamErrorHandler(IBfsErrorHandler errorhandler) : base(CultureInfo.InvariantCulture) 42 | { 43 | this.errorhandler = errorhandler; 44 | } 45 | 46 | public override Encoding Encoding 47 | { 48 | get { return Encoding.Default; } 49 | } 50 | 51 | public override void Write(string value) 52 | { 53 | errorhandler.HandleError(value); 54 | } 55 | 56 | public override void WriteLine(string value) 57 | { 58 | errorhandler.HandleError(value); 59 | } 60 | } 61 | 62 | public class ConsoleErrorHandler : IBfsErrorHandler 63 | { 64 | public bool GotError { get; set; } 65 | public void HandleMessage(string message) 66 | { 67 | Console.WriteLine("Message: " + message); 68 | } 69 | 70 | public void HandleError(string message) 71 | { 72 | Console.WriteLine("Error: " + message); 73 | GotError = true; 74 | } 75 | 76 | public void HandleError(SourceError errorMessage) 77 | { 78 | Console.WriteLine("<" + errorMessage.SourceRange.Begin + "> Error: " + errorMessage.Message); 79 | GotError = true; 80 | } 81 | 82 | public void HandleWarning(SourceError warningMessage) 83 | { 84 | Console.WriteLine("<" + warningMessage.SourceRange.Begin + "> Message: " + warningMessage.Message); 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /BinaryFileSchema/Phases/DefiniteAssignment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace BFSchema 6 | { 7 | public class DefiniteAssignment : IPhase 8 | { 9 | Dictionary topoDictionary = new Dictionary(); 10 | private BfsTopologicalNode GetTopoNode(IBfsNamedField namedField) 11 | { 12 | if (topoDictionary.ContainsKey(namedField)) 13 | return topoDictionary[namedField]; 14 | 15 | BfsTopologicalNode newNode = new BfsTopologicalNode(namedField); 16 | topoDictionary.Add(namedField, newNode); 17 | return newNode; 18 | } 19 | 20 | public void Check( BinaryFileSchema schema ) 21 | { 22 | 23 | foreach (IBfsDataBlock block in schema.DatablockList) 24 | { 25 | if (!(block is IBfsStructType)) 26 | continue; 27 | 28 | //Clear before each run as nodes will otherwise be seen as visited in the next data block. 29 | topoDictionary.Clear(); 30 | 31 | IBfsStructType structType = block as IBfsStructType; 32 | BfsTopologicalSorting topological = new BfsTopologicalSorting(); 33 | BfsTopologicalNode prevField = null; 34 | 35 | foreach ( BfsStructField field in structType.StructFieldList) 36 | { 37 | BfsTopologicalNode node = GetTopoNode(field); 38 | topological.Nodes.Add(node); 39 | 40 | //Make each struct field dependent on the previous field. 41 | if (prevField != null) 42 | node.Nodes.Add(prevField); 43 | else 44 | prevField = node; 45 | 46 | if (field.Conditional != null) 47 | foreach (BfsExpressionVariable expVar in field.Conditional.DependantVariables) 48 | node.Nodes.Add(GetTopoNode(expVar.LastField)); 49 | 50 | if (field.PrimitiveType.ArrayExtension != null && field.PrimitiveType.ArrayExtension is BfsKnownArray) 51 | { 52 | BfsKnownArray knownArray = field.PrimitiveType.ArrayExtension as BfsKnownArray; 53 | foreach (BfsExpressionVariable expVar in knownArray.Expression.DependantVariables) 54 | node.Nodes.Add(GetTopoNode(expVar.LastField)); 55 | } 56 | } 57 | 58 | //Add all the structure field as well as their dependancies 59 | foreach (BfsLocalField local in structType.LocalFieldList) 60 | { 61 | BfsTopologicalNode node = GetTopoNode(local); 62 | if(local.AssignmentExpression != null) 63 | foreach (BfsExpressionVariable expVar in local.AssignmentExpression.DependantVariables) 64 | node.Nodes.Add(GetTopoNode(expVar.LastField)); 65 | topological.Nodes.Add(node); 66 | } 67 | 68 | //Find the execution/parse order of the struct fields and local fields by performing a topological sort. 69 | structType.ParseOrder = topological.TopologicalSort(); 70 | 71 | } 72 | 73 | foreach (IBfsDataBlock block in schema.DatablockList) 74 | { 75 | //Check that local-fields aren't used in their own intialization expression. 76 | foreach (BfsLocalField local in block.LocalFieldList) 77 | if (local.AssignmentExpression != null) 78 | foreach (BfsExpressionVariable expvar in local.AssignmentExpression.DependantVariables) 79 | if (expvar.NameHierarchy[0] == local) 80 | BfsCompiler.ReportError(local.SourceRange, 81 | "Cannot use local variable in it's own initilization expression"); 82 | 83 | if (block is IBfsStructType) 84 | { 85 | bool foundEOFcase = false; 86 | BfsStructField eofCase = null; 87 | IBfsStructType structType = (IBfsStructType)block; 88 | HashSet namesSeenSoFar = new HashSet(structType.LocalFields.Keys); 89 | 90 | foreach (BfsStructField field in structType.StructFields.Values) 91 | { 92 | if (foundEOFcase) 93 | BfsCompiler.ReportError(field.SourceRange, 94 | "Array '"+eofCase.Name+"' cannot have an EOF case because there are remaining fields in the struct."); 95 | 96 | //Check that no variables in conditional expressions or array length expressions aren't read from the file yet. 97 | //Check that struct-fields aren't used in their conditional expression. 98 | if (field.Conditional != null) 99 | foreach (BfsExpressionVariable var in field.Conditional.DependantVariables) 100 | if (!namesSeenSoFar.Contains(var.NameHierarchy[0].Name) && !(var.NameHierarchy[0] is BfsEnumAliasExp)) 101 | BfsCompiler.ReportError(var.SourceRange, 102 | " The variable '" + var.ToString() + "' cannot be used before it is read from the file."); 103 | 104 | if (field.FieldType.ArrayExtension != null && field.FieldType.ArrayExtension is BfsKnownArray) 105 | { 106 | BfsKnownArray knownArray = field.FieldType.ArrayExtension as BfsKnownArray; 107 | foreach (BfsExpressionVariable var in knownArray.Expression.DependantVariables) 108 | if (!namesSeenSoFar.Contains(var.NameHierarchy[0].Name) && !(var.NameHierarchy[0] is BfsEnumAliasExp)) 109 | BfsCompiler.ReportError(var.SourceRange, 110 | " The variable '" + var.ToString() + "' cannot be used before it is read from the file."); 111 | } 112 | namesSeenSoFar.Add(field.Name); 113 | 114 | //Check that no struct fields come after an unknown array extension only terminating at EOF 115 | //Check that no stopcases comes after an EOF 116 | if (field.FieldType.ArrayExtension is BfsUnknownArray) 117 | { 118 | BfsUnknownArray extension = field.FieldType.ArrayExtension as BfsUnknownArray; 119 | bool stopcaseafter = false; 120 | foreach (IBfsStopCase stopcase in extension.StopCases) 121 | { 122 | if (stopcaseafter) 123 | BfsCompiler.ReportWarning(stopcase.SourceRange, 124 | "Stopcase after an EOF will never be triggered. Move the EOF to the end of the list."); 125 | 126 | if (stopcase is BfsStopCaseEndOfFile) 127 | { 128 | stopcaseafter = true; 129 | foundEOFcase = true; 130 | eofCase = field; 131 | } 132 | } 133 | } 134 | } 135 | } 136 | } 137 | } 138 | } 139 | 140 | 141 | 142 | 143 | } 144 | -------------------------------------------------------------------------------- /BinaryFileSchema/Phases/Environments.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace BFSchema 4 | { 5 | class Environments : IPhase 6 | { 7 | public void Check(BinaryFileSchema schema) 8 | { 9 | bool formatfound = false; 10 | foreach (IBfsDataBlock block in schema.DatablockList) 11 | { 12 | bool elsefound = false; 13 | 14 | //Check that only one block is declared 'format'. 15 | if (block.IsFormat && formatfound == false) 16 | { 17 | formatfound = true; 18 | schema.FormatBlock = block; 19 | } 20 | else if (block.IsFormat && formatfound == true) 21 | BfsCompiler.ReportError(block.SourceRange, 22 | "Only one 'format' specifier is allowed per schema"); 23 | 24 | //Check that no two blocks have the same name and build map over types. 25 | if (schema.DataBlocks.ContainsKey(block.Name)) 26 | BfsCompiler.ReportError(block.SourceRange, 27 | "Duplicate datablock name not allowed: '" + block.Name + "'"); 28 | else 29 | schema.DataBlocks.Add(block.Name, block); 30 | 31 | //Build map over local variables 32 | foreach (BfsLocalField localfield in block.LocalFieldList) 33 | if (localfield.Name == "value") 34 | BfsCompiler.ReportError(localfield.SourceRange, 35 | "'value' is a reserved name for use in expressions in consumable types."); 36 | else if (block.LocalFields.ContainsKey(localfield.Name)) 37 | BfsCompiler.ReportError(localfield.SourceRange, 38 | "Duplicate local variable name not allowed: '" + localfield.Name + "'"); 39 | else 40 | block.LocalFields.Add(localfield.Name, localfield); 41 | 42 | //Check that no two struct fields in the same block have the same name. 43 | if (block is IBfsStructType) 44 | { 45 | IBfsStructType structblock = block as IBfsStructType; 46 | foreach (BfsStructField field in structblock.StructFieldList) 47 | { 48 | if (field.Name == "value") 49 | BfsCompiler.ReportError(field.SourceRange, 50 | "'value' is a reserved name for use in expressions in consumable types."); 51 | else if (structblock.StructFields.ContainsKey(field.Name)) 52 | BfsCompiler.ReportError(field.SourceRange, 53 | "Duplicate field name not allowed: '" + field.Name + "'"); 54 | else 55 | structblock.StructFields.Add(field.Name, field); 56 | } 57 | //Check that no local variables have the same name 58 | foreach (BfsStructField field in structblock.StructFieldList) 59 | if (structblock.LocalFields.ContainsKey(field.Name)) 60 | BfsCompiler.ReportError(field.SourceRange, "Name clash with local variable: '" + field.Name + "'"); 61 | 62 | //Check that only supported compressions methods are defined 63 | if (structblock.CompressionMethod != null) 64 | if(structblock.CompressionMethod != "GZip" && structblock.CompressionMethod != "Deflate") 65 | BfsCompiler.ReportError(structblock.CompressionRange, 66 | "Unknown compression method: '" + structblock.CompressionMethod + "'. Expected 'GZip' or 'Deflate'."); 67 | } 68 | 69 | if (block is BfsEnum) 70 | { 71 | BfsEnum enumblock = block as BfsEnum; 72 | enumblock.SizeInBytes = GetSizeOfPrimitiveType(enumblock.PrimitiveType); 73 | HashSet enumvalues = new HashSet(); 74 | HashSet enumranges = new HashSet(); 75 | foreach (BfsEnumField field in enumblock.EnumFields) 76 | { 77 | //Check that there is only one 'else'. 78 | bool isElse = (field.EnumMatch is BfsEnumElse); 79 | if (isElse && elsefound == false) 80 | elsefound = true; 81 | else if (isElse && elsefound == true) 82 | BfsCompiler.ReportError(field.SourceRange, "Only one 'else' event allowed"); 83 | 84 | //Building map from name to enum field aliases 85 | if (field.Alias != null && !enumblock.EnumAliases.ContainsKey(field.Alias)) 86 | { 87 | BfsEnumFieldAlias alias = new BfsEnumFieldAlias(); 88 | alias.Name = field.Alias; 89 | enumblock.EnumAliases.Add(field.Alias, alias); 90 | } 91 | 92 | //Check that no numbers or ranges intersect. 93 | if (field.EnumMatch is BfsEnumValue) 94 | { 95 | BfsEnumValue e_val = (field.EnumMatch as BfsEnumValue); 96 | foreach (int val in enumvalues) 97 | if (e_val.Value == val) 98 | BfsCompiler.ReportError(field.SourceRange, "Value already defined: '" + val + "'"); 99 | 100 | foreach (BfsEnumRange range in enumranges) 101 | CheckValueOnRange(e_val.Value, range, field); 102 | 103 | enumvalues.Add(e_val.Value); 104 | } 105 | if (field.EnumMatch is BfsEnumRange) 106 | { 107 | BfsEnumRange range = field.EnumMatch as BfsEnumRange; 108 | 109 | if (range.EndValue <= range.StartValue) 110 | BfsCompiler.ReportError(range.SourceRange, "End-value must be larger than start-value in the range"); 111 | 112 | long actualRange = range.EndValue - range.StartValue + 1; 113 | if (range.StartInclusion == BfsInclusionEnum.Excluded) 114 | actualRange--; 115 | if (range.EndInclusion == BfsInclusionEnum.Excluded) 116 | actualRange--; 117 | 118 | if (actualRange == 0) 119 | BfsCompiler.ReportError(range.SourceRange, "Range is empty because of the inclusions brackets: '" + range + "'"); 120 | 121 | if (actualRange == 1) 122 | BfsCompiler.ReportWarning(range.SourceRange, "Range is of length 1, why not use a single value instead?: '" + range + "'"); 123 | 124 | foreach (int val in enumvalues) 125 | CheckValueOnRange(val, range, field); 126 | 127 | foreach (BfsEnumRange rb in enumranges) 128 | CheckRangeOnRange(range, rb, field); 129 | 130 | enumranges.Add(range); 131 | } 132 | } 133 | } 134 | 135 | 136 | HashSet bits = new HashSet(); 137 | HashSet bitnames = new HashSet(); 138 | if (block is BfsBitfield) 139 | { 140 | BfsBitfield bitfield = block as BfsBitfield; 141 | bitfield.SizeInBytes = GetSizeOfPrimitiveType(bitfield.PrimitiveType); 142 | foreach (BfsBitfieldField field in bitfield.BitFieldFields) 143 | { 144 | //Check that no bit-indexes are listed twice. 145 | if (bits.Contains(field.BitNumber)) 146 | BfsCompiler.ReportError(field.SourceRange, "Bit may only be listed once: '" + field.BitNumber + "'"); 147 | else 148 | bits.Add(field.BitNumber); 149 | 150 | //Check that no bit-names are listed twice. 151 | if (field.Name != null && bitnames.Contains(field.Name)) 152 | BfsCompiler.ReportError(field.SourceRange, "Two identical bitnames found: '" + field.Name + "'"); 153 | else 154 | if(field.Name != null) 155 | bitnames.Add(field.Name); 156 | 157 | //Check that the bit-indexes doesn't exeed the size of the primitive type. 158 | long sizeoftype = GetSizeOfPrimitiveType(bitfield.PrimitiveType) * 8 - 1; 159 | if (field.BitNumber > sizeoftype) 160 | BfsCompiler.ReportError(field.SourceRange, 161 | "Bit-index exceeds the boundary of the primitive type: '" + field.BitNumber + "' > " + sizeoftype); 162 | } 163 | } 164 | } 165 | if (schema.FormatBlock == null) 166 | BfsCompiler.ReportError("No 'format' block specified. Schema needs an entry point."); 167 | 168 | } 169 | 170 | private static void CheckValueOnRange(long val, BfsEnumRange range, BfsEnumField field) 171 | { 172 | if ( val < range.StartValue || val > range.EndValue) 173 | return; 174 | 175 | if (val > range.StartValue && val < range.EndValue) 176 | BfsCompiler.ReportError(field.SourceRange, "Value intersecting range is not allowed: '" + range + "'"); 177 | 178 | if (range.StartInclusion == BfsInclusionEnum.Included && val == range.StartValue 179 | || range.EndInclusion == BfsInclusionEnum.Included && val == range.EndValue) 180 | BfsCompiler.ReportError(field.SourceRange, "Value intersecting range is not allowed. Check the inclusion brackets: '" + range + "'"); 181 | } 182 | 183 | private static void CheckRangeOnRange(BfsEnumRange ra, BfsEnumRange rb, BfsEnumField field) 184 | { 185 | if (ra.StartValue > rb.EndValue || rb.StartValue > ra.EndValue) 186 | return; 187 | 188 | if( ra.EndValue == rb.StartValue && 189 | (ra.EndInclusion == BfsInclusionEnum.Excluded || rb.StartInclusion == BfsInclusionEnum.Excluded )) 190 | return; 191 | 192 | if( rb.EndValue == ra.StartValue && 193 | (rb.EndInclusion == BfsInclusionEnum.Excluded || ra.StartInclusion == BfsInclusionEnum.Excluded )) 194 | return; 195 | 196 | BfsCompiler.ReportError(field.SourceRange, "Intersecting ranges not allowed: '" + ra + "' and '" + rb + "'"); 197 | } 198 | 199 | public static int GetSizeOfPrimitiveType( BfsPrimitiveType primitiveType ) 200 | { 201 | switch (primitiveType.PrimitiveType) 202 | { 203 | case BfsPrimitiveTypeEnum.Bool: return 1; 204 | case BfsPrimitiveTypeEnum.Sbyte: return 1; 205 | case BfsPrimitiveTypeEnum.Ubyte: return 1; 206 | case BfsPrimitiveTypeEnum.Short: return 2; 207 | case BfsPrimitiveTypeEnum.Ushort: return 2; 208 | case BfsPrimitiveTypeEnum.Int: return 4; 209 | case BfsPrimitiveTypeEnum.Uint: return 4; 210 | case BfsPrimitiveTypeEnum.Long: return 4; 211 | case BfsPrimitiveTypeEnum.Ulong: return 4; 212 | case BfsPrimitiveTypeEnum.CallExpression: 213 | BfsCompiler.ReportMessage("Function type..."); 214 | return 1; 215 | } 216 | return 1; 217 | } 218 | 219 | } 220 | 221 | 222 | } 223 | -------------------------------------------------------------------------------- /BinaryFileSchema/Phases/HelperClasses.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace BFSchema 7 | { 8 | public class BfsTopologicalSorting 9 | { 10 | HashSet nodes = new HashSet(); 11 | List resultList; 12 | Stack stackVisitedNodes = new Stack(); 13 | 14 | public HashSet Nodes { get { return nodes; } } 15 | 16 | public List TopologicalSort() 17 | { 18 | resultList = new List(); 19 | 20 | foreach (BfsTopologicalNode node in nodes) 21 | Visit(node); 22 | 23 | //resultList.Reverse(); 24 | return resultList; 25 | } 26 | 27 | private void Visit(BfsTopologicalNode node) 28 | { 29 | //If the node was found in the depth stack, report an error as this means a circular dependence was found. 30 | if (stackVisitedNodes.Contains(node)) 31 | { 32 | List reversed = new List(stackVisitedNodes); 33 | reversed.Reverse(); 34 | StringBuilder b = new StringBuilder("A circular depencence was detected: "); 35 | foreach (BfsTopologicalNode topoNode in reversed) 36 | b.Append( topoNode.NamedField.Name + " -> "); 37 | b.Append(node.NamedField.Name); 38 | BfsCompiler.ReportError(node.NamedField.SourceRange,b.ToString()); 39 | } 40 | 41 | if (!node.Visited) 42 | { 43 | node.Visited = true; 44 | stackVisitedNodes.Push(node); 45 | foreach (BfsTopologicalNode subnode in node.Nodes) 46 | Visit(subnode); 47 | stackVisitedNodes.Pop(); 48 | if(this.nodes.Contains(node)) 49 | resultList.Add(node.NamedField); 50 | } 51 | } 52 | } 53 | 54 | public class BfsTopologicalNode 55 | { 56 | public IBfsNamedField NamedField { get; set; } 57 | HashSet nodes = new HashSet(); 58 | public HashSet Nodes { get { return nodes; } } 59 | 60 | public bool Visited { get; set; } 61 | 62 | public BfsTopologicalNode(IBfsNamedField field) 63 | { 64 | NamedField = field; 65 | } 66 | public override string ToString() 67 | { 68 | return NamedField.ToString(); 69 | } 70 | } 71 | 72 | public class ByteArrayConverter 73 | { 74 | public static byte [] ConvertString(string text) 75 | { 76 | char[] chars = text.Substring(1,text.Length-2).ToCharArray(); 77 | byte[] bytes = new byte[chars.Length]; 78 | for (int i = 0; i < chars.Length; i++) 79 | bytes[i] = (byte)chars[i]; 80 | return bytes; 81 | } 82 | 83 | public static byte[] ConvertHexString(string hex) 84 | { 85 | if (!hex.StartsWith("0x")) 86 | BfsCompiler.ReportError("Could not convert hex string to byte array!"); 87 | 88 | hex = hex.Substring(2); 89 | 90 | int numberChars = hex.Length; 91 | byte[] bytes = new byte[numberChars / 2]; 92 | for (int i = 0; i < numberChars; i += 2) 93 | bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); 94 | return bytes; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /BinaryFileSchema/Phases/Hierarchy.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace BFSchema 3 | { 4 | class Hierarchy : IPhase 5 | { 6 | private BinaryFileSchema schema; 7 | 8 | public void Check( BinaryFileSchema schema ) 9 | { 10 | this.schema = schema; 11 | 12 | foreach (IBfsDataBlock block in schema.DatablockList) 13 | { 14 | //Generate map over unresolved expression variables; 15 | foreach (BfsLocalField field in block.LocalFields.Values) 16 | if (field.AssignmentExpression != null) 17 | CheckExpression(field.AssignmentExpression, block); 18 | 19 | if (block is IBfsStructType) 20 | { 21 | IBfsStructType structType = (IBfsStructType)block; 22 | 23 | foreach (BfsStructField field in structType.StructFields.Values) 24 | { 25 | //Check conditional expressions 26 | if (field.Conditional != null) 27 | CheckExpression(field.Conditional, block); 28 | 29 | if (field.FieldType.ArrayExtension != null) 30 | if(field.FieldType.ArrayExtension is BfsKnownArray) 31 | CheckExpression((field.FieldType.ArrayExtension as BfsKnownArray).Expression, block); 32 | //Check that no unknown sized arrays are located within any structure that is compressed (seeking not allowed) 33 | else if(field.FieldType.ArrayExtension is BfsUnknownArray && structType.CompressionMethod != null) 34 | BfsCompiler.ReportError(field.FieldType.ArrayExtension.SourceRange, 35 | "Cannot have unknown sized arrays within compressed blocks: '" + field.Name + "'"); 36 | 37 | } 38 | } 39 | else if (block is BfsEnum) 40 | { 41 | foreach( BfsEnumField field in (block as BfsEnum).EnumFields) 42 | if(field.Actions != null) 43 | foreach( IBfsAction action in field.Actions ) 44 | if( action is BfsActionAssignment ) 45 | CheckExpression((action as BfsActionAssignment).Expression, block); 46 | } 47 | else if (block is BfsBitfield) 48 | { 49 | foreach (BfsBitfieldField field in (block as BfsBitfield).BitFieldFields) 50 | if (field.Actions != null) 51 | foreach (IBfsAction action in field.Actions) 52 | if (action is BfsActionAssignment) 53 | CheckExpression((action as BfsActionAssignment).Expression, block); 54 | } 55 | } 56 | } 57 | 58 | private void CheckExpression(BfsExpression expression, IBfsDataBlock block) 59 | { 60 | CheckExpressionNode(expression, expression.ExpressionGroup, block); 61 | CheckForEnumMembers(expression.ExpressionGroup, block); 62 | } 63 | 64 | private void CheckExpressionNode(BfsExpression exp, BfsExpGroup group, IBfsDataBlock block) 65 | { 66 | for (int index = 0; index < group.Members.Count; index++) 67 | { 68 | IBfsExpNode node = group.Members[index]; 69 | 70 | if (node is BfsOperator) 71 | continue; 72 | 73 | if (node is BfsExpGroup) 74 | CheckExpressionNode(exp, node as BfsExpGroup, block); 75 | else if (node is BfsCallExp) 76 | { 77 | BfsCallExp call = node as BfsCallExp; 78 | if (call.FunctionName != "sizeof") 79 | { 80 | BfsCompiler.ReportError(call.NameSourceRange, 81 | "Unknown function: '" + call.FunctionName + "'"); 82 | break; 83 | } 84 | //If the argument in sizeof(data-block) can be found. 85 | else if (schema.DataBlocks.ContainsKey(call.FunctionArgument)) 86 | { 87 | if (schema.DataBlocks[call.FunctionArgument] is IBfsStructType) 88 | CalculateStructSize(call.SourceRange, schema.DataBlocks[call.FunctionArgument] as IBfsStructType); 89 | 90 | call.SizeInBytes = schema.DataBlocks[call.FunctionArgument].SizeInBytes; 91 | continue; 92 | } 93 | else 94 | BfsCompiler.ReportError(call.ArgumentSourceRange, 95 | "Could not find the data-block: '"+call.FunctionArgument+"'"); 96 | } 97 | else if (node is BfsUnresolvedVariableExp) 98 | { 99 | BfsUnresolvedVariableExp unresolved = node as BfsUnresolvedVariableExp; 100 | 101 | //Boolean(true/false)? 102 | if (unresolved.ToString() == "true" || unresolved.ToString() == "false") 103 | { 104 | BfsBooleanExp booleanExp = new BfsBooleanExp(); 105 | booleanExp.SourceRange = unresolved.SourceRange; 106 | booleanExp.Value = (unresolved.ToString() == "true") ? true : false; 107 | group.Members.Insert(index, booleanExp); 108 | group.Members.Remove(unresolved); 109 | continue; 110 | } 111 | 112 | //Value expression? 113 | if (unresolved.ToString() == "value") 114 | { 115 | if (block is IBfsConsumptionType) 116 | { 117 | BfsValueExp valueExp = new BfsValueExp(); 118 | valueExp.SourceRange = unresolved.SourceRange; 119 | group.Members.Insert(index, valueExp); 120 | group.Members.Remove(unresolved); 121 | continue; 122 | } 123 | else 124 | { 125 | BfsCompiler.ReportError(unresolved.SourceRange, 126 | "The 'value' expression variable may only be used in consumed types."); 127 | continue; 128 | } 129 | } 130 | 131 | //Else it is a named variable. 132 | BfsExpressionVariable namedVar = new BfsExpressionVariable(); 133 | 134 | namedVar.SourceRange = node.SourceRange; 135 | 136 | group.Members.Insert(index, namedVar); 137 | group.Members.Remove(node); 138 | 139 | string containertype = block.ToString(); 140 | 141 | //Check hiearchy 142 | IBfsDataBlock container = block; 143 | for (int i = 0; i < unresolved.NameHierarchy.Count; i++) 144 | { 145 | string varname = unresolved.NameHierarchy[i]; 146 | if (container == null) 147 | { 148 | BfsCompiler.ReportError(node.SourceRange, 149 | "Variable '" + unresolved.NameHierarchy[i - 1] + "' cannot contain any variables because it of type: " + containertype); 150 | break; 151 | } 152 | 153 | if (container.LocalFields.ContainsKey(varname)) 154 | { 155 | namedVar.NameHierarchy.Add(container.LocalFields[varname]); 156 | containertype = " local variable"; 157 | container = null; 158 | } 159 | else if (container is IBfsStructType && (container as IBfsStructType).StructFields.ContainsKey(varname)) 160 | { 161 | IBfsType type = (container as IBfsStructType).StructFields[varname].FieldType; 162 | IBfsNamedField namedtype = (container as IBfsStructType).StructFields[varname]; 163 | 164 | if (type is BfsNamedType) 165 | { 166 | container = (type as BfsNamedType).DataBlock; 167 | 168 | if (container is IBfsConsumptionType) 169 | { 170 | IBfsConsumptionType consumed = container as IBfsConsumptionType; 171 | namedtype.PrimitiveType = consumed.PrimitiveType; 172 | } 173 | 174 | namedVar.NameHierarchy.Add(namedtype); 175 | } 176 | else if (type is BfsPrimitiveType) 177 | { 178 | containertype = "primitive type"; 179 | namedVar.NameHierarchy.Add(namedtype); 180 | container = null; 181 | } 182 | else if (type is BfsFunctionType) 183 | { 184 | containertype = "function type"; 185 | namedVar.NameHierarchy.Add(namedtype); 186 | container = null; 187 | } 188 | else BfsCompiler.ReportError(container.SourceRange, "Unexpected error. Unknown type."); 189 | } 190 | else 191 | { 192 | containertype = "unknown variable or enum-alias."; 193 | BfsExpressionUnknown unknown = new BfsExpressionUnknown(); 194 | unknown.Name = varname; 195 | unknown.SourceRange = unresolved.SourceRange; 196 | namedVar.NameHierarchy.Add(unknown); 197 | container = null; 198 | } 199 | } 200 | //Building map over dependant variables. 201 | exp.DependantVariables.Add(namedVar); 202 | } 203 | } 204 | } 205 | 206 | private void CheckForEnumMembers(BfsExpGroup group, IBfsDataBlock block) 207 | { 208 | //For each expression variable in the expression group 209 | for (int index = 0; index < group.Members.Count; index++) 210 | { 211 | //Recursively visit the sub-expressions 212 | IBfsExpNode node = group.Members[index]; 213 | if (node is BfsExpGroup) 214 | { 215 | CheckForEnumMembers(node as BfsExpGroup, block); 216 | continue; 217 | } 218 | 219 | //Ignore irrelevant objects (operators and known variables) 220 | if (!(node is BfsExpressionVariable)) 221 | continue; 222 | BfsExpressionVariable expressionvar = node as BfsExpressionVariable; 223 | if (!(expressionvar.LastField is BfsExpressionUnknown)) 224 | continue; 225 | 226 | //Only interested in resolving the BfsExpressionUnknowns 227 | BfsExpressionUnknown unknown = expressionvar.LastField as BfsExpressionUnknown; 228 | 229 | BfsExpressionVariable candidatevar = null; 230 | bool resolvedTheVar = false; 231 | 232 | BfsOperator op = null; 233 | 234 | if (index >= 2 && group.Members[index - 2] is BfsExpressionVariable) 235 | { 236 | op = group.Members[index - 1] as BfsOperator; 237 | candidatevar = group.Members[index - 2] as BfsExpressionVariable; 238 | } 239 | else if (index + 2 < group.Members.Count && group.Members[index + 2] is BfsExpressionVariable) 240 | { 241 | op = group.Members[index + 1] as BfsOperator; 242 | candidatevar = group.Members[index + 2] as BfsExpressionVariable; 243 | } 244 | 245 | 246 | if ( candidatevar != null 247 | && candidatevar.LastField is BfsStructField 248 | && (candidatevar.LastField as BfsStructField).FieldType is BfsNamedType) 249 | { 250 | BfsStructField field = candidatevar.LastField as BfsStructField; 251 | BfsNamedType fieldtype = field.FieldType as BfsNamedType; 252 | 253 | if (fieldtype.DataBlock is BfsEnum && (fieldtype.DataBlock as BfsEnum).EnumAliases.ContainsKey(unknown.Name)) 254 | { 255 | resolvedTheVar = true; 256 | BfsEnumFieldAlias enumalias = (fieldtype.DataBlock as BfsEnum).EnumAliases[unknown.Name]; 257 | BfsEnumAliasExp aliasExp = new BfsEnumAliasExp(); 258 | aliasExp.EnumBlock = fieldtype.DataBlock as BfsEnum; 259 | aliasExp.Alias = enumalias; 260 | aliasExp.SourceRange = unknown.SourceRange; 261 | 262 | //Only allow equality operators on EnumAliases 263 | if (op.Operator == "==" || op.Operator == "!=") 264 | { 265 | group.Members.Insert(index, aliasExp); 266 | group.Members.Remove(node); 267 | } 268 | else 269 | BfsCompiler.ReportError(op.SourceRange, 270 | "The operator '"+op.Operator+"' cannot be used with the enum alias '"+enumalias.Name+"'. Only == and != are allowed."); 271 | 272 | expressionvar.LastField = aliasExp; 273 | } 274 | } 275 | 276 | if(!resolvedTheVar) 277 | BfsCompiler.ReportError(unknown.SourceRange, 278 | "Unresolved variable name: '" + unknown.Name + "'"); 279 | } 280 | } 281 | 282 | private void CalculateStructSize(BfsSourceRange range, IBfsStructType structtype) 283 | { 284 | int totalstructsize = 0; 285 | foreach (BfsStructField field in structtype.StructFieldList) 286 | { 287 | if (field.PrimitiveType.ArrayExtension == null) 288 | totalstructsize += Environments.GetSizeOfPrimitiveType(field.PrimitiveType); 289 | else 290 | if (field.PrimitiveType.ArrayExtension is BfsKnownArray) 291 | { 292 | BfsKnownArray known = field.PrimitiveType.ArrayExtension as BfsKnownArray; 293 | BfsExpGroup expgroup = known.Expression.ExpressionGroup; 294 | if (expgroup.Members.Count == 1 && expgroup.Members[0] is BfsNumberExp) 295 | { 296 | totalstructsize += Environments.GetSizeOfPrimitiveType(field.PrimitiveType) 297 | * (int)(expgroup.Members[0] as BfsNumberExp).Value; 298 | //BfsCompiler.ReportMessage("Known array of size: " + (expgroup.Members[0] as BfsNumberExp).Value); 299 | } 300 | else 301 | BfsCompiler.ReportError(range, 302 | "Could not get size of block '"+structtype.Name+"' as it has a field with non-simple array-extension."); 303 | } 304 | else 305 | { 306 | totalstructsize = 0; 307 | BfsCompiler.ReportError(range, 308 | "Cannot get size of a block with unknown size (because of array extension in: '" + structtype.Name + "." + field.Name + "')"); 309 | break; 310 | } 311 | } 312 | structtype.SizeInBytes = totalstructsize; 313 | //BfsCompiler.ReportWarning(structtype.SourceRange, "Total size of struct: "+ totalstructsize); 314 | } 315 | 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /BinaryFileSchema/Phases/TypeChecking.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace BFSchema 7 | { 8 | public class TypeChecking : IPhase 9 | { 10 | public void Check( BinaryFileSchema schema ) 11 | { 12 | foreach (IBfsDataBlock block in schema.DatablockList) 13 | { 14 | //Assignment expressions on local variables 15 | foreach (BfsLocalField local in block.LocalFieldList) 16 | if (local.AssignmentExpression != null) 17 | { 18 | if (local.PrimitiveType.ArrayExtension != null) 19 | BfsCompiler.ReportError(local.SourceRange, 20 | "Local variables with array extensions cannot have assignment expressions."); 21 | 22 | CheckExpression(local.AssignmentExpression, block); 23 | CheckAssignment(local.SourceRange, local.PrimitiveType.PrimitiveType, local.AssignmentExpression.PrimitiveType); 24 | } 25 | 26 | //Check conditional expressions + array extensions 27 | if (block is IBfsStructType) 28 | { 29 | IBfsStructType structType = (IBfsStructType)block; 30 | foreach (BfsStructField field in structType.StructFields.Values) 31 | { 32 | if (field.Conditional != null) 33 | { 34 | CheckExpression(field.Conditional, block); 35 | if (field.Conditional.PrimitiveType != BfsPrimitiveTypeEnum.Bool) 36 | BfsCompiler.ReportError(field.Conditional.SourceRange, 37 | "The conditional isn't of boolean type!"); 38 | } 39 | 40 | if (field.FieldType.ArrayExtension != null && field.FieldType.ArrayExtension is BfsKnownArray) 41 | { 42 | BfsKnownArray arr = field.FieldType.ArrayExtension as BfsKnownArray; 43 | CheckExpression(arr.Expression, block); 44 | if (arr.Expression.PrimitiveType <= BfsPrimitiveTypeEnum.Bool 45 | && arr.Expression.PrimitiveType != BfsPrimitiveTypeEnum.CallExpression) 46 | BfsCompiler.ReportError(arr.SourceRange, 47 | "Unsuitable type for array-extension: " + arr.Expression.PrimitiveType ); 48 | } 49 | } 50 | } 51 | // All the expressions in action-lists for both Enums and BitFields 52 | else if (block is BfsEnum) 53 | { 54 | foreach (BfsEnumField field in (block as BfsEnum).EnumFields) 55 | if (field.Actions != null) 56 | foreach (IBfsAction action in field.Actions) 57 | if (action is BfsActionAssignment) 58 | { 59 | BfsActionAssignment a = action as BfsActionAssignment; 60 | CheckExpression(a.Expression, block); 61 | CheckAssignment(a.SourceRange, a.LocalVariable.PrimitiveType.PrimitiveType, a.Expression.PrimitiveType); 62 | } 63 | } 64 | else if (block is BfsBitfield) 65 | { 66 | foreach (BfsBitfieldField field in (block as BfsBitfield).BitFieldFields) 67 | if (field.Actions != null) 68 | foreach (IBfsAction action in field.Actions) 69 | if (action is BfsActionAssignment) 70 | { 71 | BfsActionAssignment a = action as BfsActionAssignment; 72 | CheckExpression(a.Expression, block); 73 | CheckAssignment(a.SourceRange, a.LocalVariable.PrimitiveType.PrimitiveType, a.Expression.PrimitiveType); 74 | } 75 | } 76 | } 77 | } 78 | 79 | private void CheckExpression(BfsExpression expression, IBfsDataBlock block) 80 | { 81 | CheckGroup(expression.ExpressionGroup, block); 82 | //BfsCompiler.ReportWarning(expression.ExpressionGroup.SourceRange, expression.ToString() + ": " + expression.PrimitiveType); 83 | } 84 | 85 | private void CheckGroup( BfsExpGroup group, IBfsDataBlock block ) 86 | { 87 | foreach (IBfsExpNode node in group.Members) 88 | { 89 | if (node is BfsNumberExp) 90 | CheckType(group, BfsPrimitiveTypeEnum.Int, block); 91 | else if (node is BfsBooleanExp) 92 | CheckType(group, BfsPrimitiveTypeEnum.Bool, block); 93 | else if (node is BfsCallExp) 94 | CheckType(group, BfsPrimitiveTypeEnum.CallExpression, block); 95 | else if (node is BfsExpressionVariable) 96 | { 97 | BfsExpressionVariable expvar = node as BfsExpressionVariable; 98 | 99 | //Check if the type of the variable is a function type (like ascii("Hello")) 100 | if (expvar.LastField is BfsStructField) 101 | if ((expvar.LastField as BfsStructField).FieldType is BfsFunctionType) 102 | BfsCompiler.ReportError(expvar.SourceRange, "Cannot have function types in expressions!"); 103 | 104 | CheckType(group, expvar.PrimitiveType, block); 105 | 106 | //Checking if any part of an expression variable references a variable that is array-extended 107 | foreach( IBfsNamedField field in expvar.NameHierarchy ) 108 | if (field is BfsStructField) 109 | { 110 | BfsStructField f = field as BfsStructField; 111 | if (f != null) 112 | { 113 | if (f.FieldType.ArrayExtension != null) 114 | BfsCompiler.ReportError(expvar.SourceRange, 115 | "Cannot use array-extended type in expression: '" + expvar + "'"); 116 | 117 | if (f.Skip) 118 | BfsCompiler.ReportError(expvar.SourceRange, 119 | "The variable '" + expvar + "' has been marked as skipped data and therefore cannot be used in expressions."); 120 | } 121 | } 122 | } 123 | else if (node is BfsEnumAliasExp) 124 | CheckType(group, BfsPrimitiveTypeEnum.EnumMember, block); 125 | else if (node is BfsOperator) 126 | CheckOperator(group, node as BfsOperator); 127 | else if (node is BfsExpGroup) 128 | { 129 | BfsExpGroup g = node as BfsExpGroup; 130 | CheckGroup(g, block); 131 | //Compare the subgroups type to the parents (this) type. 132 | CheckType(group, g.PrimitiveType, block); 133 | 134 | //If the group consists of comparissons then the type of the group must be boolean. 135 | if (g.OperatorPrecedenceLevel == BfsExpGroupOperatorLevel.Comparisson) 136 | group.PrimitiveType = BfsPrimitiveTypeEnum.Bool; 137 | } 138 | } 139 | } 140 | 141 | private void CheckOperator(BfsExpGroup group, BfsOperator op) 142 | { 143 | //Just a formality check if the operators in the same group actually do belong to the same operator precedence-group 144 | if (group.OperatorPrecedenceLevel == BfsExpGroupOperatorLevel.Undetermined) 145 | group.OperatorPrecedenceLevel = op.PrecendenceLevel; 146 | else if (group.OperatorPrecedenceLevel != op.PrecendenceLevel) 147 | BfsCompiler.ReportError(op.SourceRange,"Mixed operator-precedence groups! '" 148 | + op + "' doesn't belong in '"+group.OperatorPrecedenceLevel+"'"); 149 | } 150 | 151 | private void CheckType(BfsExpGroup group, BfsPrimitiveTypeEnum type, IBfsDataBlock block) 152 | { 153 | //If boolean and non-boolean types are mixed. 154 | if((group.PrimitiveType == BfsPrimitiveTypeEnum.Bool && type > BfsPrimitiveTypeEnum.Bool)) 155 | BfsCompiler.ReportError(group.SourceRange, "Cannot mix boolean and " + type + " types"); 156 | else if(type == BfsPrimitiveTypeEnum.Bool && group.PrimitiveType > BfsPrimitiveTypeEnum.Bool) 157 | BfsCompiler.ReportError(group.SourceRange, "Cannot mix boolean and " + group.PrimitiveType + " types"); 158 | 159 | //if (type == BfsPrimitiveTypeEnum.FunctionType || group.PrimitiveType == BfsPrimitiveTypeEnum.FunctionType) 160 | // BfsCompiler.ReportError(group.SourceRange, "You cannot use function typed variables in expressions"); 161 | 162 | if (type == BfsPrimitiveTypeEnum.Undetermined) 163 | BfsCompiler.ReportError(group.SourceRange,"Undetermined type of variable"); 164 | 165 | //If all is well then it will pick the largest type that can contain the variable. 166 | //Hiearchy: Undetermined,Bool,Ubyte,Sbyte,Ushort,Short,Uint,Int,Ulong,Long 167 | BfsPrimitiveTypeEnum a = group.PrimitiveType; 168 | BfsPrimitiveTypeEnum b = type; 169 | group.PrimitiveType = (a > b) ? a : b; 170 | } 171 | 172 | private void CheckAssignment(BfsSourceRange range, BfsPrimitiveTypeEnum target, BfsPrimitiveTypeEnum newvar) 173 | { 174 | if (target < newvar) 175 | BfsCompiler.ReportError(range,"The type '"+newvar+"' could not be stored into the type '"+target+"'"); 176 | } 177 | 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /BinaryFileSchema/Phases/TypeLinking.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace BFSchema 7 | { 8 | class TypeLinking : IPhase 9 | { 10 | public void Check(BinaryFileSchema schema) 11 | { 12 | foreach (IBfsDataBlock block in schema.DatablockList) 13 | { 14 | //Link all unresolved field-types to their declarations (data-blocks). 15 | if (block is IBfsStructType) 16 | { 17 | IBfsStructType structType = block as IBfsStructType; 18 | foreach (BfsStructField field in structType.StructFields.Values) 19 | if (field.FieldType is BfsUnresolvedNamedType) 20 | { 21 | BfsUnresolvedNamedType oldtype = (BfsUnresolvedNamedType)field.FieldType; 22 | if (schema.DataBlocks.ContainsKey(oldtype.Name)) 23 | { 24 | BfsNamedType newtype = new BfsNamedType(); 25 | newtype.DataBlock = schema.DataBlocks[oldtype.Name]; 26 | newtype.ArrayExtension = oldtype.ArrayExtension; 27 | newtype.SourceRange = oldtype.SourceRange; 28 | field.FieldType = newtype; 29 | } 30 | else BfsCompiler.ReportError(oldtype.SourceRange, "Could not resolve '" + oldtype.Name + "' to a type."); 31 | } 32 | } 33 | else if (block is BfsEnum) 34 | foreach (BfsEnumField field in (block as BfsEnum).EnumFields) 35 | CheckActionList(field.Actions, block); 36 | else if (block is BfsBitfield) 37 | foreach (BfsBitfieldField field in (block as BfsBitfield).BitFieldFields) 38 | CheckActionList(field.Actions, block); 39 | } 40 | } 41 | 42 | 43 | 44 | private static void CheckActionList(IList actions, IBfsDataBlock block) 45 | { 46 | if (actions == null) 47 | return; 48 | 49 | for( int index = 0; index < actions.Count; index++) 50 | { 51 | IBfsAction action = actions[index]; 52 | 53 | if (action is BfsActionUnresolvedAssignment) 54 | { 55 | BfsActionUnresolvedAssignment unresolved = action as BfsActionUnresolvedAssignment; 56 | BfsActionAssignment assignment = new BfsActionAssignment(); 57 | assignment.Expression = unresolved.Expression; 58 | assignment.SourceRange = unresolved.SourceRange; 59 | if (block.LocalFields.ContainsKey(unresolved.UnresolvedVariableName)) 60 | assignment.LocalVariable = block.LocalFields[unresolved.UnresolvedVariableName]; 61 | else 62 | BfsCompiler.ReportError(assignment.SourceRange, 63 | "Could not find local variable: '"+unresolved.UnresolvedVariableName+"'"); 64 | 65 | actions.Insert(index, assignment); 66 | actions.Remove(action); 67 | } 68 | } 69 | } 70 | 71 | 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /BinaryFileSchema/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Binary File Schema")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("BinaryFileSchema")] 13 | [assembly: AssemblyCopyright("Anders Riggelsen © 2008")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("6dcb3920-d87b-4488-8cea-1d9244a0c92c")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/BFSGUI.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace BinaryFileSchemaGUI 2 | { 3 | partial class BFSGUI 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BFSGUI)); 33 | this.toolStrip1 = new System.Windows.Forms.ToolStrip(); 34 | this.toolNewSchema = new System.Windows.Forms.ToolStripButton(); 35 | this.toolOpenSchema = new System.Windows.Forms.ToolStripButton(); 36 | this.toolSaveSchema = new System.Windows.Forms.ToolStripButton(); 37 | this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); 38 | this.toolCompileSchema = new System.Windows.Forms.ToolStripButton(); 39 | this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); 40 | this.toolComboLanguage = new System.Windows.Forms.ToolStripComboBox(); 41 | this.toolGenerateCode = new System.Windows.Forms.ToolStripButton(); 42 | this.toolAbout = new System.Windows.Forms.ToolStripButton(); 43 | this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); 44 | this.splitContainer1 = new System.Windows.Forms.SplitContainer(); 45 | this.richTextBox = new BinaryFileSchemaGUI.FastRichEdit(); 46 | this.listViewErrorBox = new System.Windows.Forms.ListView(); 47 | this.columnMessage = new System.Windows.Forms.ColumnHeader(); 48 | this.imageListErrorIcons = new System.Windows.Forms.ImageList(this.components); 49 | this.splitContainer2 = new System.Windows.Forms.SplitContainer(); 50 | this.treeBFSstructure = new System.Windows.Forms.TreeView(); 51 | this.imgListBlocks = new System.Windows.Forms.ImageList(this.components); 52 | this.saveFileDialog = new System.Windows.Forms.SaveFileDialog(); 53 | this.toolStrip1.SuspendLayout(); 54 | this.splitContainer1.Panel1.SuspendLayout(); 55 | this.splitContainer1.Panel2.SuspendLayout(); 56 | this.splitContainer1.SuspendLayout(); 57 | this.splitContainer2.Panel1.SuspendLayout(); 58 | this.splitContainer2.Panel2.SuspendLayout(); 59 | this.splitContainer2.SuspendLayout(); 60 | this.SuspendLayout(); 61 | // 62 | // toolStrip1 63 | // 64 | this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 65 | this.toolNewSchema, 66 | this.toolOpenSchema, 67 | this.toolSaveSchema, 68 | this.toolStripSeparator1, 69 | this.toolCompileSchema, 70 | this.toolStripSeparator2, 71 | this.toolComboLanguage, 72 | this.toolGenerateCode, 73 | this.toolAbout}); 74 | this.toolStrip1.Location = new System.Drawing.Point(0, 0); 75 | this.toolStrip1.Name = "toolStrip1"; 76 | this.toolStrip1.Size = new System.Drawing.Size(720, 25); 77 | this.toolStrip1.TabIndex = 1; 78 | this.toolStrip1.Text = "toolStrip1"; 79 | // 80 | // toolNewSchema 81 | // 82 | this.toolNewSchema.Image = global::BinaryFileSchemaGUI.Properties.Resources.page; 83 | this.toolNewSchema.ImageTransparentColor = System.Drawing.Color.Magenta; 84 | this.toolNewSchema.Name = "toolNewSchema"; 85 | this.toolNewSchema.Size = new System.Drawing.Size(51, 22); 86 | this.toolNewSchema.Text = "New"; 87 | this.toolNewSchema.ToolTipText = "New Schema"; 88 | this.toolNewSchema.Click += new System.EventHandler(this.toolNewSchema_Click); 89 | // 90 | // toolOpenSchema 91 | // 92 | this.toolOpenSchema.Image = global::BinaryFileSchemaGUI.Properties.Resources.folder; 93 | this.toolOpenSchema.ImageTransparentColor = System.Drawing.Color.Magenta; 94 | this.toolOpenSchema.Name = "toolOpenSchema"; 95 | this.toolOpenSchema.Size = new System.Drawing.Size(56, 22); 96 | this.toolOpenSchema.Text = "Open"; 97 | this.toolOpenSchema.Click += new System.EventHandler(this.toolStripButton2_Click); 98 | // 99 | // toolSaveSchema 100 | // 101 | this.toolSaveSchema.Image = global::BinaryFileSchemaGUI.Properties.Resources.disk1; 102 | this.toolSaveSchema.ImageTransparentColor = System.Drawing.Color.Magenta; 103 | this.toolSaveSchema.Name = "toolSaveSchema"; 104 | this.toolSaveSchema.Size = new System.Drawing.Size(51, 22); 105 | this.toolSaveSchema.Text = "Save"; 106 | this.toolSaveSchema.Click += new System.EventHandler(this.toolSaveSchema_Click); 107 | // 108 | // toolStripSeparator1 109 | // 110 | this.toolStripSeparator1.Name = "toolStripSeparator1"; 111 | this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); 112 | // 113 | // toolCompileSchema 114 | // 115 | this.toolCompileSchema.Image = global::BinaryFileSchemaGUI.Properties.Resources.control_play_blue; 116 | this.toolCompileSchema.ImageTransparentColor = System.Drawing.Color.Magenta; 117 | this.toolCompileSchema.Name = "toolCompileSchema"; 118 | this.toolCompileSchema.Size = new System.Drawing.Size(72, 22); 119 | this.toolCompileSchema.Text = "Compile"; 120 | this.toolCompileSchema.Click += new System.EventHandler(this.toolStripButton1_Click); 121 | // 122 | // toolStripSeparator2 123 | // 124 | this.toolStripSeparator2.Name = "toolStripSeparator2"; 125 | this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); 126 | // 127 | // toolComboLanguage 128 | // 129 | this.toolComboLanguage.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 130 | this.toolComboLanguage.DropDownWidth = 64; 131 | this.toolComboLanguage.Name = "toolComboLanguage"; 132 | this.toolComboLanguage.Size = new System.Drawing.Size(75, 25); 133 | // 134 | // toolGenerateCode 135 | // 136 | this.toolGenerateCode.Enabled = false; 137 | this.toolGenerateCode.Image = global::BinaryFileSchemaGUI.Properties.Resources.cog_go; 138 | this.toolGenerateCode.ImageTransparentColor = System.Drawing.Color.Magenta; 139 | this.toolGenerateCode.Name = "toolGenerateCode"; 140 | this.toolGenerateCode.Size = new System.Drawing.Size(103, 22); 141 | this.toolGenerateCode.Text = "Generate code"; 142 | this.toolGenerateCode.Click += new System.EventHandler(this.toolGenerateCode_Click); 143 | // 144 | // toolAbout 145 | // 146 | this.toolAbout.Image = global::BinaryFileSchemaGUI.Properties.Resources.help; 147 | this.toolAbout.ImageTransparentColor = System.Drawing.Color.Magenta; 148 | this.toolAbout.Name = "toolAbout"; 149 | this.toolAbout.Size = new System.Drawing.Size(60, 22); 150 | this.toolAbout.Text = "About"; 151 | this.toolAbout.ToolTipText = "About"; 152 | this.toolAbout.Visible = false; 153 | this.toolAbout.Click += new System.EventHandler(this.toolAbout_Click); 154 | // 155 | // openFileDialog 156 | // 157 | this.openFileDialog.FileName = "*.fsc"; 158 | this.openFileDialog.Filter = "Binary File Schemas|*.fsc|All files|*.*"; 159 | // 160 | // splitContainer1 161 | // 162 | this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; 163 | this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; 164 | this.splitContainer1.Location = new System.Drawing.Point(0, 0); 165 | this.splitContainer1.Name = "splitContainer1"; 166 | this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; 167 | // 168 | // splitContainer1.Panel1 169 | // 170 | this.splitContainer1.Panel1.Controls.Add(this.richTextBox); 171 | // 172 | // splitContainer1.Panel2 173 | // 174 | this.splitContainer1.Panel2.Controls.Add(this.listViewErrorBox); 175 | this.splitContainer1.Size = new System.Drawing.Size(525, 430); 176 | this.splitContainer1.SplitterDistance = 279; 177 | this.splitContainer1.TabIndex = 2; 178 | // 179 | // richTextBox 180 | // 181 | this.richTextBox.AcceptsTab = true; 182 | this.richTextBox.AllowPaint = true; 183 | this.richTextBox.Dock = System.Windows.Forms.DockStyle.Fill; 184 | this.richTextBox.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 185 | this.richTextBox.ForeColor = System.Drawing.Color.Black; 186 | this.richTextBox.HideSelection = false; 187 | this.richTextBox.Location = new System.Drawing.Point(0, 0); 188 | this.richTextBox.Name = "richTextBox"; 189 | this.richTextBox.Size = new System.Drawing.Size(525, 279); 190 | this.richTextBox.TabIndex = 0; 191 | this.richTextBox.Text = ""; 192 | this.richTextBox.WordWrap = false; 193 | // 194 | // listViewErrorBox 195 | // 196 | this.listViewErrorBox.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { 197 | this.columnMessage}); 198 | this.listViewErrorBox.Dock = System.Windows.Forms.DockStyle.Fill; 199 | this.listViewErrorBox.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; 200 | this.listViewErrorBox.HideSelection = false; 201 | this.listViewErrorBox.Location = new System.Drawing.Point(0, 0); 202 | this.listViewErrorBox.MultiSelect = false; 203 | this.listViewErrorBox.Name = "listViewErrorBox"; 204 | this.listViewErrorBox.ShowGroups = false; 205 | this.listViewErrorBox.Size = new System.Drawing.Size(525, 147); 206 | this.listViewErrorBox.SmallImageList = this.imageListErrorIcons; 207 | this.listViewErrorBox.TabIndex = 1; 208 | this.listViewErrorBox.UseCompatibleStateImageBehavior = false; 209 | this.listViewErrorBox.View = System.Windows.Forms.View.Details; 210 | this.listViewErrorBox.ItemActivate += new System.EventHandler(this.listViewErrorBox_ItemActivate); 211 | // 212 | // columnMessage 213 | // 214 | this.columnMessage.Text = "Message"; 215 | this.columnMessage.Width = 521; 216 | // 217 | // imageListErrorIcons 218 | // 219 | this.imageListErrorIcons.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageListErrorIcons.ImageStream"))); 220 | this.imageListErrorIcons.TransparentColor = System.Drawing.Color.Transparent; 221 | this.imageListErrorIcons.Images.SetKeyName(0, "information.png"); 222 | this.imageListErrorIcons.Images.SetKeyName(1, "error.png"); 223 | this.imageListErrorIcons.Images.SetKeyName(2, "stop.png"); 224 | // 225 | // splitContainer2 226 | // 227 | this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; 228 | this.splitContainer2.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; 229 | this.splitContainer2.Location = new System.Drawing.Point(0, 25); 230 | this.splitContainer2.Name = "splitContainer2"; 231 | // 232 | // splitContainer2.Panel1 233 | // 234 | this.splitContainer2.Panel1.BackColor = System.Drawing.SystemColors.Control; 235 | this.splitContainer2.Panel1.Controls.Add(this.splitContainer1); 236 | // 237 | // splitContainer2.Panel2 238 | // 239 | this.splitContainer2.Panel2.Controls.Add(this.treeBFSstructure); 240 | this.splitContainer2.Size = new System.Drawing.Size(720, 430); 241 | this.splitContainer2.SplitterDistance = 525; 242 | this.splitContainer2.TabIndex = 3; 243 | // 244 | // treeBFSstructure 245 | // 246 | this.treeBFSstructure.Dock = System.Windows.Forms.DockStyle.Fill; 247 | this.treeBFSstructure.ImageKey = "page_white_text.png"; 248 | this.treeBFSstructure.ImageList = this.imgListBlocks; 249 | this.treeBFSstructure.Location = new System.Drawing.Point(0, 0); 250 | this.treeBFSstructure.Name = "treeBFSstructure"; 251 | this.treeBFSstructure.SelectedImageIndex = 0; 252 | this.treeBFSstructure.Size = new System.Drawing.Size(191, 430); 253 | this.treeBFSstructure.TabIndex = 0; 254 | this.treeBFSstructure.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeBFSstructure_AfterSelect); 255 | // 256 | // imgListBlocks 257 | // 258 | this.imgListBlocks.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgListBlocks.ImageStream"))); 259 | this.imgListBlocks.TransparentColor = System.Drawing.Color.Transparent; 260 | this.imgListBlocks.Images.SetKeyName(0, "database.png"); 261 | this.imgListBlocks.Images.SetKeyName(1, "database_go.png"); 262 | this.imgListBlocks.Images.SetKeyName(2, "comments.png"); 263 | this.imgListBlocks.Images.SetKeyName(3, "brick.png"); 264 | this.imgListBlocks.Images.SetKeyName(4, "bullet_blue.png"); 265 | // 266 | // saveFileDialog 267 | // 268 | this.saveFileDialog.FileName = "*.fsc"; 269 | this.saveFileDialog.Filter = "Binary File Schemas|*.fsc|All files|*.*"; 270 | // 271 | // BFSGUI 272 | // 273 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 274 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 275 | this.ClientSize = new System.Drawing.Size(720, 455); 276 | this.Controls.Add(this.splitContainer2); 277 | this.Controls.Add(this.toolStrip1); 278 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 279 | this.Name = "BFSGUI"; 280 | this.Text = "Binary File Schema"; 281 | this.Load += new System.EventHandler(this.Form1_Load); 282 | this.toolStrip1.ResumeLayout(false); 283 | this.toolStrip1.PerformLayout(); 284 | this.splitContainer1.Panel1.ResumeLayout(false); 285 | this.splitContainer1.Panel2.ResumeLayout(false); 286 | this.splitContainer1.ResumeLayout(false); 287 | this.splitContainer2.Panel1.ResumeLayout(false); 288 | this.splitContainer2.Panel2.ResumeLayout(false); 289 | this.splitContainer2.ResumeLayout(false); 290 | this.ResumeLayout(false); 291 | this.PerformLayout(); 292 | 293 | } 294 | 295 | #endregion 296 | 297 | private System.Windows.Forms.ToolStrip toolStrip1; 298 | private System.Windows.Forms.ToolStripButton toolCompileSchema; 299 | private System.Windows.Forms.OpenFileDialog openFileDialog; 300 | private System.Windows.Forms.SplitContainer splitContainer1; 301 | private System.Windows.Forms.ToolStripButton toolOpenSchema; 302 | private System.Windows.Forms.SplitContainer splitContainer2; 303 | private System.Windows.Forms.TreeView treeBFSstructure; 304 | private System.Windows.Forms.ImageList imgListBlocks; 305 | private System.Windows.Forms.ListView listViewErrorBox; 306 | private System.Windows.Forms.ColumnHeader columnMessage; 307 | private System.Windows.Forms.ImageList imageListErrorIcons; 308 | private FastRichEdit richTextBox; 309 | private System.Windows.Forms.ToolStripButton toolNewSchema; 310 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; 311 | private System.Windows.Forms.ToolStripButton toolAbout; 312 | private System.Windows.Forms.ToolStripButton toolGenerateCode; 313 | private System.Windows.Forms.ToolStripComboBox toolComboLanguage; 314 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; 315 | private System.Windows.Forms.ToolStripButton toolSaveSchema; 316 | private System.Windows.Forms.SaveFileDialog saveFileDialog; 317 | } 318 | } 319 | 320 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/BFSGUI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Windows.Forms; 4 | using BFSchema; 5 | using Peg.Base; 6 | using System.Diagnostics; 7 | 8 | namespace BinaryFileSchemaGUI 9 | { 10 | public partial class BFSGUI : Form 11 | { 12 | public BFSGUI() 13 | { 14 | InitializeComponent(); 15 | } 16 | 17 | BinaryFileSchema lastSchema; 18 | string openFile = string.Empty; 19 | 20 | private void Form1_Load(object sender, EventArgs e) 21 | { 22 | /*string filename = @"C:\"; 23 | if (File.Exists(filename)) 24 | { 25 | LoadGrammar(filename); 26 | ParseGrammar(); 27 | }*/ 28 | toolComboLanguage.Items.Add(new BFSchema.CodeGenerators.CSharp.CSharpGenerator()); 29 | toolComboLanguage.SelectedIndex = 0; 30 | } 31 | 32 | private void toolStripButton1_Click(object sender, EventArgs e) 33 | { 34 | ParseGrammar(); 35 | } 36 | 37 | private void toolStripButton2_Click(object sender, EventArgs e) 38 | { 39 | DialogResult res = openFileDialog.ShowDialog(); 40 | if (res == DialogResult.OK) 41 | { 42 | LoadGrammar(openFileDialog.FileName); 43 | ParseGrammar(); 44 | } 45 | } 46 | 47 | private void LoadGrammar( string filename ) 48 | { 49 | if (!File.Exists(filename)) 50 | return; 51 | 52 | StreamReader reader = new StreamReader(filename); 53 | string source = reader.ReadToEnd(); 54 | richTextBox.Text = source; 55 | reader.Close(); 56 | richTextBox.Select(0, 0); 57 | openFile = filename; 58 | toolSaveSchema.Enabled = true; 59 | } 60 | 61 | private void ParseGrammar( ) 62 | { 63 | richTextBox.AllowPaint = false; 64 | treeBFSstructure.BeginUpdate(); 65 | listViewErrorBox.BeginUpdate(); 66 | 67 | IBfsErrorHandler errorHandler = new ListViewErrorHandler(listViewErrorBox); 68 | string source = richTextBox.Text; 69 | 70 | listViewErrorBox.Items.Clear(); 71 | treeBFSstructure.Nodes.Clear(); 72 | 73 | Stopwatch timer = new Stopwatch(); 74 | timer.Start(); 75 | BinaryFileSchema schema = BfsCompiler.ParseBfs(source, errorHandler); 76 | timer.Stop(); 77 | 78 | if (schema != null) 79 | { 80 | errorHandler.HandleMessage("Parsed and processed in " + timer.ElapsedMilliseconds + " milliseconds (" + timer.ElapsedTicks + " ticks)"); 81 | IterateSchema(schema); 82 | SchemaColorizer.ColorizeSchema(schema, richTextBox); 83 | toolGenerateCode.Enabled = true; 84 | lastSchema = schema; 85 | } 86 | else 87 | toolGenerateCode.Enabled = false; 88 | 89 | richTextBox.AllowPaint = true; 90 | treeBFSstructure.EndUpdate(); 91 | listViewErrorBox.EndUpdate(); 92 | } 93 | 94 | private string GetNodeText(PegNode node, string source) 95 | { 96 | return source.Substring(node.match_.posBeg_, node.match_.Length).Trim(); 97 | } 98 | 99 | private void treeBFSstructure_AfterSelect(object sender, TreeViewEventArgs e) 100 | { 101 | IBfsSourceNode snode = e.Node.Tag as IBfsSourceNode; 102 | 103 | if (snode != null) 104 | richTextBox.Select(snode.SourceRange.Begin, snode.SourceRange.Length); 105 | else 106 | listViewErrorBox.Items.Add("Error! No range was stored in the nodes!",0); 107 | } 108 | 109 | private void IterateSchema( BinaryFileSchema schema ) 110 | { 111 | foreach (IBfsDataBlock block in schema.DatablockList) 112 | { 113 | TreeNode node = treeBFSstructure.Nodes.Add(block.Name); 114 | node.Tag = block; 115 | node.ImageIndex = node.SelectedImageIndex = 0; 116 | 117 | if (block is IBfsStructType) 118 | { 119 | if (block is IBfsConsumptionType) 120 | node.ImageIndex = node.SelectedImageIndex = 1; 121 | 122 | foreach (BfsStructField field in (block as IBfsStructType).StructFields.Values) 123 | { 124 | TreeNode newnode = node.Nodes.Add(field.ToString()); 125 | newnode.Tag = field; 126 | newnode.ImageIndex = newnode.SelectedImageIndex = 4; 127 | } 128 | } 129 | else if (block is BfsEnum) 130 | { 131 | node.ImageIndex = node.SelectedImageIndex = 2; 132 | foreach (BfsEnumField field in (block as BfsEnum).EnumFields) 133 | { 134 | TreeNode newnode = node.Nodes.Add(field.ToString()); 135 | newnode.Tag = field; 136 | newnode.ImageIndex = newnode.SelectedImageIndex = 4; 137 | } 138 | } 139 | else if (block is BfsBitfield) 140 | { 141 | node.ImageIndex = node.SelectedImageIndex = 3; 142 | foreach (BfsBitfieldField field in (block as BfsBitfield).BitFieldFields) 143 | { 144 | TreeNode newnode = node.Nodes.Add(field.ToString()); 145 | newnode.Tag = field; 146 | newnode.ImageIndex = newnode.SelectedImageIndex = 4; 147 | } 148 | } 149 | node.Expand(); 150 | } 151 | } 152 | 153 | private void listViewErrorBox_ItemActivate(object sender, EventArgs e) 154 | { 155 | if (listViewErrorBox.SelectedItems.Count == 0) 156 | return; 157 | 158 | if (listViewErrorBox.SelectedItems[0].Tag is SourceError) 159 | { 160 | SourceError error = listViewErrorBox.SelectedItems[0].Tag as SourceError; 161 | richTextBox.Select(error.SourceRange.Begin, error.SourceRange.Length); 162 | richTextBox.Focus(); 163 | return; 164 | } 165 | else 166 | { 167 | string message = listViewErrorBox.SelectedItems[0].Text; 168 | if (message.StartsWith("<")) 169 | { 170 | string[] items = message.Split("<,>".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 171 | int line = Math.Max(int.Parse(items[0]) - 1,0); 172 | int index = int.Parse(items[1]); 173 | int begin = Math.Max(richTextBox.GetFirstCharIndexFromLine(line), 0); 174 | int end = Math.Max(richTextBox.GetFirstCharIndexFromLine(line + 1) - begin, 0); 175 | richTextBox.Select(begin, end); 176 | richTextBox.Focus(); 177 | } 178 | } 179 | } 180 | 181 | private void toolNewSchema_Click(object sender, EventArgs e) 182 | { 183 | richTextBox.Clear(); 184 | toolGenerateCode.Enabled = false; 185 | openFile = string.Empty; 186 | } 187 | 188 | private void toolAbout_Click(object sender, EventArgs e) 189 | { 190 | MessageBox.Show("Binary File Schema - By Anders Riggelsen, www.andersriggelsen.dk", "About Binary File Schema", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); 191 | } 192 | 193 | private void toolGenerateCode_Click(object sender, EventArgs e) 194 | { 195 | CodeGenerator generator = toolComboLanguage.SelectedItem as CodeGenerator; 196 | string sourceCode = generator.GenerateCode(lastSchema); 197 | CodeOutput codeDialog = new CodeOutput(sourceCode, lastSchema.FormatBlock.Name); 198 | codeDialog.ShowDialog(); 199 | } 200 | 201 | private void toolSaveSchema_Click(object sender, EventArgs e) 202 | { 203 | if (openFile == string.Empty) 204 | { 205 | DialogResult res = saveFileDialog.ShowDialog(); 206 | if (res == DialogResult.OK) 207 | openFile = saveFileDialog.FileName; 208 | else 209 | return; 210 | } 211 | 212 | StreamWriter writer = new StreamWriter(openFile); 213 | writer.Write(richTextBox.Text); 214 | writer.Close(); 215 | } 216 | 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/BinaryFileSchemaGUI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {0FBAE211-1E37-4CE8-AE39-59E67D78F4A8} 9 | WinExe 10 | Properties 11 | BinaryFileSchemaGUI 12 | BinaryFileSchemaGUI 13 | v3.5 14 | 512 15 | 16 | 17 | binary_large.ico 18 | false 19 | 20 | 21 | publish\ 22 | true 23 | Disk 24 | false 25 | Foreground 26 | 7 27 | Days 28 | false 29 | false 30 | true 31 | 0 32 | 1.0.0.%2a 33 | false 34 | false 35 | true 36 | false 37 | 38 | 39 | true 40 | full 41 | false 42 | bin\Debug\ 43 | DEBUG;TRACE 44 | prompt 45 | 4 46 | true 47 | 48 | 49 | pdbonly 50 | true 51 | bin\Release\ 52 | TRACE 53 | prompt 54 | 4 55 | true 56 | 57 | 58 | 59 | 60 | 3.5 61 | 62 | 63 | 3.5 64 | 65 | 66 | 3.5 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Form 77 | 78 | 79 | BFSGUI.cs 80 | 81 | 82 | Form 83 | 84 | 85 | CodeOutput.cs 86 | 87 | 88 | Component 89 | 90 | 91 | 92 | 93 | 94 | 95 | BFSGUI.cs 96 | Designer 97 | 98 | 99 | CodeOutput.cs 100 | Designer 101 | 102 | 103 | ResXFileCodeGenerator 104 | Resources.Designer.cs 105 | Designer 106 | 107 | 108 | True 109 | Resources.resx 110 | True 111 | 112 | 113 | SettingsSingleFileGenerator 114 | Settings.Designer.cs 115 | 116 | 117 | True 118 | Settings.settings 119 | True 120 | 121 | 122 | 123 | 124 | 125 | {B99A0149-B187-4075-AD79-A36A084BF73A} 126 | BinaryFileSchema 127 | 128 | 129 | {9913580D-1543-40D5-B463-14C95BF3120C} 130 | PEG Base 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | False 149 | .NET Framework 2.0 %28x86%29 150 | false 151 | 152 | 153 | False 154 | .NET Framework 3.0 %28x86%29 155 | false 156 | 157 | 158 | False 159 | .NET Framework 3.5 160 | true 161 | 162 | 163 | False 164 | Windows Installer 3.1 165 | true 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 180 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/CodeOutput.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace BinaryFileSchemaGUI 2 | { 3 | partial class CodeOutput 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.toolStrip1 = new System.Windows.Forms.ToolStrip(); 32 | this.toolStripSave = new System.Windows.Forms.ToolStripButton(); 33 | this.richEditSourceCode = new BinaryFileSchemaGUI.FastRichEdit(); 34 | this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); 35 | this.toolStrip1.SuspendLayout(); 36 | this.SuspendLayout(); 37 | // 38 | // toolStrip1 39 | // 40 | this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 41 | this.toolStripSave}); 42 | this.toolStrip1.Location = new System.Drawing.Point(0, 0); 43 | this.toolStrip1.Name = "toolStrip1"; 44 | this.toolStrip1.Size = new System.Drawing.Size(783, 25); 45 | this.toolStrip1.TabIndex = 0; 46 | this.toolStrip1.Text = "toolStrip1"; 47 | // 48 | // toolStripSave 49 | // 50 | this.toolStripSave.Image = global::BinaryFileSchemaGUI.Properties.Resources.disk; 51 | this.toolStripSave.ImageTransparentColor = System.Drawing.Color.Magenta; 52 | this.toolStripSave.Name = "toolStripSave"; 53 | this.toolStripSave.Size = new System.Drawing.Size(80, 22); 54 | this.toolStripSave.Text = "Save code"; 55 | this.toolStripSave.Click += new System.EventHandler(this.toolStripSave_Click); 56 | // 57 | // richEditSourceCode 58 | // 59 | this.richEditSourceCode.AcceptsTab = true; 60 | this.richEditSourceCode.AllowPaint = true; 61 | this.richEditSourceCode.Dock = System.Windows.Forms.DockStyle.Fill; 62 | this.richEditSourceCode.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 63 | this.richEditSourceCode.Location = new System.Drawing.Point(0, 25); 64 | this.richEditSourceCode.Name = "richEditSourceCode"; 65 | this.richEditSourceCode.Size = new System.Drawing.Size(783, 445); 66 | this.richEditSourceCode.TabIndex = 1; 67 | this.richEditSourceCode.Text = ""; 68 | // 69 | // saveFileDialog1 70 | // 71 | this.saveFileDialog1.DefaultExt = "cs"; 72 | this.saveFileDialog1.Filter = "C# files|*.cs|All files|*.*"; 73 | // 74 | // CodeOutput 75 | // 76 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 77 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 78 | this.ClientSize = new System.Drawing.Size(783, 470); 79 | this.Controls.Add(this.richEditSourceCode); 80 | this.Controls.Add(this.toolStrip1); 81 | this.Name = "CodeOutput"; 82 | this.Text = "Code Output"; 83 | this.toolStrip1.ResumeLayout(false); 84 | this.toolStrip1.PerformLayout(); 85 | this.ResumeLayout(false); 86 | this.PerformLayout(); 87 | 88 | } 89 | 90 | #endregion 91 | 92 | private System.Windows.Forms.ToolStrip toolStrip1; 93 | private System.Windows.Forms.ToolStripButton toolStripSave; 94 | private FastRichEdit richEditSourceCode; 95 | private System.Windows.Forms.SaveFileDialog saveFileDialog1; 96 | } 97 | } -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/CodeOutput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace BinaryFileSchemaGUI 5 | { 6 | public partial class CodeOutput : Form 7 | { 8 | string filename = "Parser"; 9 | 10 | public CodeOutput( string sourceCode, string filename ) 11 | { 12 | InitializeComponent(); 13 | richEditSourceCode.Text = sourceCode; 14 | this.filename = filename; 15 | } 16 | 17 | private void toolStripSave_Click(object sender, EventArgs e) 18 | { 19 | saveFileDialog1.FileName = filename + "Parser.cs"; 20 | DialogResult res = saveFileDialog1.ShowDialog(); 21 | if (res == DialogResult.OK) 22 | { 23 | richEditSourceCode.SaveFile(saveFileDialog1.FileName, RichTextBoxStreamType.PlainText); 24 | } 25 | } 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/CodeOutput.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 122, 17 125 | 126 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/FastRichEdit.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows.Forms; 6 | using System.Drawing; 7 | using System.Runtime.InteropServices; 8 | 9 | namespace BinaryFileSchemaGUI 10 | { 11 | public class FastRichEdit : RichTextBox 12 | { 13 | const short WM_PAINT = 0x00f; 14 | const short WM_USER = 0x0400; 15 | const short EM_GETSCROLLPOS = WM_USER + 221; 16 | const short EM_SETSCROLLPOS = WM_USER + 222; 17 | 18 | bool allowPaint = true; 19 | int pos = 0; 20 | int length = 0; 21 | Point scrollpos = new Point(); 22 | 23 | public bool AllowPaint 24 | { 25 | get { return allowPaint; } 26 | set 27 | { 28 | if (allowPaint == false && value == true) 29 | { 30 | this.Select(pos, length); 31 | SetScrollPos(scrollpos); 32 | this.Enabled = true; 33 | this.Focus(); 34 | } 35 | else if (value == false) 36 | { 37 | pos = this.SelectionStart; 38 | length = this.SelectionLength; 39 | scrollpos = this.GetScrollPos(); 40 | this.Enabled = false; 41 | } 42 | allowPaint = value; 43 | } 44 | } 45 | 46 | protected override void WndProc(ref Message m) 47 | { 48 | if (m.Msg == WM_PAINT) 49 | { 50 | if (AllowPaint) 51 | base.WndProc(ref m); 52 | else 53 | m.Result = IntPtr.Zero; 54 | } 55 | else 56 | base.WndProc (ref m); 57 | } 58 | 59 | [StructLayout(LayoutKind.Sequential)] 60 | private struct SeqPoint 61 | { 62 | public int x; 63 | public int y; 64 | } 65 | 66 | private unsafe Point GetScrollPos() 67 | { 68 | SeqPoint res = new SeqPoint(); 69 | IntPtr ptr = new IntPtr(&res); 70 | Message m = Message.Create(this.Handle, EM_GETSCROLLPOS, IntPtr.Zero, ptr); 71 | this.WndProc(ref m); 72 | return new Point(res.x,res.y); 73 | } 74 | 75 | private unsafe void SetScrollPos( Point p ) 76 | { 77 | SeqPoint res = new SeqPoint(); 78 | res.x = p.X; 79 | res.y = p.Y; 80 | IntPtr ptr = new IntPtr(&res); 81 | Message m = Message.Create(this.Handle, EM_SETSCROLLPOS, IntPtr.Zero, ptr); 82 | this.WndProc(ref m); 83 | } 84 | 85 | 86 | 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/ListBoxErrorHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | using System.Windows.Forms; 7 | using BFSchema; 8 | 9 | namespace BinaryFileSchemaGUI 10 | { 11 | public class ListBoxErrorHandler : IBfsErrorHandler 12 | { 13 | ListBox box; 14 | public ListBoxErrorHandler(ListBox listbox) 15 | { 16 | box = listbox; 17 | } 18 | 19 | public void HandleMessage(string message) 20 | { 21 | box.Items.Add(message); 22 | } 23 | 24 | public void HandleWarning(SourceError warning) 25 | { 26 | box.Items.Add(warning); 27 | } 28 | 29 | public void HandleError(SourceError error) 30 | { 31 | box.Items.Add(error); 32 | } 33 | 34 | public void HandleError(string error) 35 | { 36 | box.Items.Add(error); 37 | } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/ListViewErrorHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | using System.Windows.Forms; 7 | using BFSchema; 8 | 9 | namespace BinaryFileSchemaGUI 10 | { 11 | public class ListViewErrorHandler : IBfsErrorHandler 12 | { 13 | ListView box; 14 | public ListViewErrorHandler(ListView listview) 15 | { 16 | box = listview; 17 | } 18 | 19 | public void HandleMessage(string message) 20 | { 21 | box.Items.Add(message, 0); 22 | } 23 | 24 | public void HandleWarning(SourceError warning) 25 | { 26 | ListViewItem item = box.Items.Add(warning.Message, 1); 27 | item.Tag = warning; 28 | } 29 | 30 | public void HandleError(SourceError error) 31 | { 32 | ListViewItem item = box.Items.Add(error.Message, 2); 33 | item.Tag = error; 34 | } 35 | 36 | public void HandleError(string error) 37 | { 38 | ListViewItem item = box.Items.Add(error, 2); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | [assembly: CLSCompliant(true)] 7 | namespace BinaryFileSchemaGUI 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new BFSGUI()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using System.Resources; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("BinaryFileSchemaGUI")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("BinaryFileSchemaGUI")] 14 | [assembly: AssemblyCopyright("Copyright © 2008")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("d27cb7bd-3c94-44e6-adf3-8cee15a64a2c")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("1.0.0.0")] 37 | [assembly: AssemblyFileVersion("1.0.0.0")] 38 | [assembly: NeutralResourcesLanguageAttribute("en")] 39 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:2.0.50727.4927 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace BinaryFileSchemaGUI.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BinaryFileSchemaGUI.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | internal static System.Drawing.Bitmap cog_go { 64 | get { 65 | object obj = ResourceManager.GetObject("cog_go", resourceCulture); 66 | return ((System.Drawing.Bitmap)(obj)); 67 | } 68 | } 69 | 70 | internal static System.Drawing.Bitmap control_play_blue { 71 | get { 72 | object obj = ResourceManager.GetObject("control_play_blue", resourceCulture); 73 | return ((System.Drawing.Bitmap)(obj)); 74 | } 75 | } 76 | 77 | internal static System.Drawing.Bitmap disk { 78 | get { 79 | object obj = ResourceManager.GetObject("disk", resourceCulture); 80 | return ((System.Drawing.Bitmap)(obj)); 81 | } 82 | } 83 | 84 | internal static System.Drawing.Bitmap disk1 { 85 | get { 86 | object obj = ResourceManager.GetObject("disk1", resourceCulture); 87 | return ((System.Drawing.Bitmap)(obj)); 88 | } 89 | } 90 | 91 | internal static System.Drawing.Bitmap folder { 92 | get { 93 | object obj = ResourceManager.GetObject("folder", resourceCulture); 94 | return ((System.Drawing.Bitmap)(obj)); 95 | } 96 | } 97 | 98 | internal static System.Drawing.Bitmap help { 99 | get { 100 | object obj = ResourceManager.GetObject("help", resourceCulture); 101 | return ((System.Drawing.Bitmap)(obj)); 102 | } 103 | } 104 | 105 | internal static System.Drawing.Bitmap page { 106 | get { 107 | object obj = ResourceManager.GetObject("page", resourceCulture); 108 | return ((System.Drawing.Bitmap)(obj)); 109 | } 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\folder.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Resources\control_play_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | ..\Resources\help.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\Resources\page.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | ..\Resources\cog_go.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | 137 | ..\Resources\disk.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 138 | 139 | 140 | ..\Resources\disk1.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 141 | 142 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:2.0.50727.1434 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace BinaryFileSchemaGUI.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Resources/cog_go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/BinaryFileSchemaGUI/Resources/cog_go.png -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Resources/control_play_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/BinaryFileSchemaGUI/Resources/control_play_blue.png -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Resources/disk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/BinaryFileSchemaGUI/Resources/disk.png -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Resources/disk1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/BinaryFileSchemaGUI/Resources/disk1.png -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Resources/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/BinaryFileSchemaGUI/Resources/folder.png -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Resources/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/BinaryFileSchemaGUI/Resources/help.png -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/Resources/page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/BinaryFileSchemaGUI/Resources/page.png -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/SchemaColorizer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using BFSchema; 4 | using System.Windows.Forms; 5 | using System.Drawing; 6 | 7 | namespace BinaryFileSchemaGUI 8 | { 9 | class SchemaColorizer 10 | { 11 | static readonly Font normalfont = new Font(FontFamily.GenericMonospace, 9.75f, FontStyle.Regular); 12 | static Font boldfont = new Font(FontFamily.GenericMonospace, 9.75f, FontStyle.Bold); 13 | 14 | static Color normalcolor = Color.Black; 15 | static Color keywordcolor = Color.Blue; 16 | static Color typecolor = Color.FromArgb(43, 145, 175); 17 | static Color numbercolor = Color.FromArgb(223, 112, 0); 18 | static Color enumaliascolor = Color.FromArgb(0, 128, 255); 19 | static Color functioncolor = Color.Red; 20 | static Color skipcolor = Color.Red; 21 | static Color stringcolor = Color.DarkRed; 22 | static Color compressioncolor = Color.DarkGoldenrod; 23 | 24 | static RichTextBox textBox; 25 | 26 | public static void ColorizeSchema(BinaryFileSchema schema, RichTextBox richTextBox) 27 | { 28 | textBox = richTextBox; 29 | richTextBox.SelectAll(); 30 | richTextBox.SelectionColor = Color.Black; 31 | richTextBox.SelectionFont = normalfont; 32 | 33 | //Colorize the byte-order 34 | if ( schema.ByteOrder != null && schema.ByteOrder.ByteOrder != BfsByteOrderEnum.LanguageDefault) 35 | { 36 | richTextBox.Select(schema.ByteOrder.SourceRange.Begin, schema.ByteOrder.SourceRange.Length); 37 | richTextBox.SelectionColor = keywordcolor; 38 | } 39 | 40 | foreach (IBfsDataBlock block in schema.DatablockList) 41 | { 42 | ColorRange(block.SourceRange, normalcolor, boldfont); 43 | ColorRange(block.BlockTypeSourceRange, keywordcolor, boldfont); 44 | 45 | if (block.IsFormat) 46 | ColorRange(block.FormatSourceRange, keywordcolor, boldfont); 47 | 48 | if (block is IBfsConsumptionType) 49 | { 50 | IBfsConsumptionType special = block as IBfsConsumptionType; 51 | ColorRange(special.PrimitiveType.SourceRange, typecolor); 52 | } 53 | 54 | foreach (BfsLocalField lfield in block.LocalFields.Values) 55 | { 56 | ColorRange(lfield.SourceRange, 5, keywordcolor); 57 | ColorRange(lfield.PrimitiveType.SourceRange, typecolor); 58 | 59 | if (lfield.AssignmentExpression != null) 60 | ColorExpression(lfield.AssignmentExpression.ExpressionGroup); 61 | } 62 | 63 | if (block is IBfsStructType) 64 | { 65 | IBfsStructType structtype = block as IBfsStructType; 66 | 67 | if (structtype.CompressionMethod != null) 68 | ColorRange(structtype.CompressionRange, compressioncolor); 69 | 70 | foreach (BfsStructField field in structtype.StructFields.Values) 71 | { 72 | ColorRange(field.FieldType.SourceRange, typecolor); 73 | if (field.FieldType is BfsFunctionType) 74 | ColorRange((field.FieldType as BfsFunctionType).ArgumentSourceRange, stringcolor); 75 | 76 | if (field.Conditional != null) 77 | { 78 | ColorRange(field.ConditionalSourceRange, 2, keywordcolor); 79 | ColorExpression(field.Conditional.ExpressionGroup); 80 | } 81 | 82 | if (field.Skip) 83 | ColorRange(field.SkipSourceRange, skipcolor); 84 | 85 | if (field.FieldType.ArrayExtension != null && field.FieldType.ArrayExtension is BfsKnownArray) 86 | ColorExpression((field.FieldType.ArrayExtension as BfsKnownArray).Expression.ExpressionGroup); 87 | else if (field.FieldType.ArrayExtension != null && field.FieldType.ArrayExtension is BfsUnknownArray) 88 | { 89 | BfsUnknownArray array = field.FieldType.ArrayExtension as BfsUnknownArray; 90 | 91 | ColorRange(array.UntilSourceRange, keywordcolor); 92 | 93 | foreach (BfsSourceRange range in array.OrWords) 94 | ColorRange(range, keywordcolor); 95 | 96 | foreach (IBfsStopCase stopcase in array.StopCases) 97 | { 98 | if (stopcase is BfsStopCaseString) 99 | ColorRange(stopcase.SourceRange, stringcolor); 100 | else if (stopcase is BfsStopCaseEndOfFile) 101 | ColorRange(stopcase.SourceRange, enumaliascolor); 102 | else if (stopcase is BfsStopCaseHex) 103 | ColorRange(stopcase.SourceRange, numbercolor); 104 | 105 | BfsSourceRange zerorange = new BfsSourceRange(); 106 | if (stopcase.InclusionSourceRange != zerorange) 107 | ColorRange(stopcase.InclusionSourceRange, keywordcolor); 108 | } 109 | 110 | } 111 | } 112 | } 113 | else if (block is BfsEnum) 114 | foreach (BfsEnumField field in (block as BfsEnum).EnumFields) 115 | { 116 | if (field.Alias != null) 117 | ColorRange(field.AliasSourceRange, enumaliascolor); 118 | 119 | if (field.EnumMatch is BfsEnumValue) 120 | ColorRange(field.EnumMatch.SourceRange, numbercolor); 121 | else if (field.EnumMatch is BfsEnumRange) 122 | ColorRange(field.EnumMatch.SourceRange.Begin + 1, field.EnumMatch.SourceRange.Length - 2, numbercolor); 123 | else if (field.EnumMatch is BfsEnumElse) 124 | ColorRange(field.EnumMatch.SourceRange, keywordcolor); 125 | 126 | ColorActionList(field.Actions); 127 | } 128 | else if (block is BfsBitfield) 129 | { 130 | foreach (BfsBitfieldField field in (block as BfsBitfield).BitFieldFields) 131 | { 132 | ColorRange(field.SourceRange, numbercolor); 133 | ColorActionList(field.Actions); 134 | } 135 | } 136 | } 137 | } 138 | 139 | private static void ColorActionList(IList actions) 140 | { 141 | if (actions == null) 142 | return; 143 | 144 | foreach (IBfsAction action in actions) 145 | { 146 | if (action is BfsActionAssignment) 147 | { 148 | BfsActionAssignment assignmentAction = action as BfsActionAssignment; 149 | ColorExpression(assignmentAction.Expression.ExpressionGroup); 150 | } 151 | else if (action is BfsActionOutput) 152 | { 153 | BfsActionOutput outputAction = action as BfsActionOutput; 154 | ColorRange(outputAction.SourceRange, functioncolor); 155 | ColorRange(outputAction.ArgumentSourceRange, stringcolor); 156 | } 157 | else throw new Exception("Unresolved assignment detected: " + action); 158 | } 159 | } 160 | 161 | 162 | private static void ColorExpression(BfsExpGroup group) 163 | { 164 | if (group == null) 165 | return; 166 | 167 | foreach (IBfsExpNode node in group.Members) 168 | { 169 | //Put nodes here that should have been replaced in the TypeLinking phase. 170 | //if (node is BfsUnresolvedVariableExp) 171 | //throw new Exception("Unresolved variable expression detected!"); 172 | 173 | if (node is BfsExpGroup) 174 | ColorExpression(node as BfsExpGroup); 175 | else if (node is BfsBooleanExp) 176 | { 177 | BfsBooleanExp exp = node as BfsBooleanExp; 178 | ColorRange(exp.SourceRange, keywordcolor); 179 | } 180 | else if (node is BfsNumberExp) 181 | { 182 | BfsNumberExp val = node as BfsNumberExp; 183 | ColorRange(val.SourceRange, numbercolor); 184 | } 185 | else if (node is BfsOperator) 186 | { 187 | //TODO 188 | } 189 | else if (node is BfsValueExp) 190 | { 191 | BfsValueExp val = node as BfsValueExp; 192 | ColorRange(val.SourceRange, keywordcolor); 193 | } 194 | else if (node is BfsEnumAliasExp) 195 | { 196 | BfsEnumAliasExp val = node as BfsEnumAliasExp; 197 | ColorRange(val.SourceRange, enumaliascolor); 198 | } 199 | else if (node is BfsCallExp) 200 | { 201 | BfsCallExp val = node as BfsCallExp; 202 | ColorRange(val.NameSourceRange, keywordcolor); 203 | ColorRange(val.ArgumentSourceRange, typecolor); 204 | } 205 | } 206 | } 207 | 208 | private static void ColorRange( BfsSourceRange range, Color color ) 209 | { 210 | textBox.Select(range.Begin, range.Length); 211 | textBox.SelectionColor = color; 212 | } 213 | private static void ColorRange(BfsSourceRange range, int length, Color color) 214 | { 215 | textBox.Select(range.Begin,length); 216 | textBox.SelectionColor = color; 217 | } 218 | private static void ColorRange(int begin, int length, Color color) 219 | { 220 | textBox.Select(begin, length); 221 | textBox.SelectionColor = color; 222 | } 223 | private static void ColorRange(BfsSourceRange range, Color color, Font font) 224 | { 225 | textBox.Select(range.Begin, range.Length); 226 | textBox.SelectionColor = color; 227 | textBox.SelectionFont = font; 228 | } 229 | } 230 | 231 | } 232 | -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/binary.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/BinaryFileSchemaGUI/binary.ico -------------------------------------------------------------------------------- /BinaryFileSchemaGUI/binary_large.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/BinaryFileSchemaGUI/binary_large.ico -------------------------------------------------------------------------------- /CommandLineGenerator/CommandLineGenerator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {B569D745-AAB4-47CB-AAF7-80351C36E31D} 9 | Exe 10 | Properties 11 | CommandLineGenerator 12 | WebGenerator 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 3.5 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | {B99A0149-B187-4075-AD79-A36A084BF73A} 47 | BinaryFileSchema 48 | 49 | 50 | 51 | 58 | -------------------------------------------------------------------------------- /CommandLineGenerator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BFSchema; 3 | using BFSchema.CodeGenerators.CSharp; 4 | 5 | namespace CommandLineGenerator 6 | { 7 | class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | //Command line code generator 12 | 13 | if (args.Length == 0) 14 | { 15 | Console.WriteLine("Error: No input schema..."); 16 | return; 17 | } 18 | 19 | ConsoleErrorHandler errorHandler = new ConsoleErrorHandler(); 20 | BinaryFileSchema schema = new BinaryFileSchema(args[0], errorHandler); 21 | if (schema == null || errorHandler.GotError) 22 | { 23 | Console.WriteLine("Could not generate C# code because of schema errors!"); 24 | return; 25 | } 26 | CSharpGenerator csgenerator = new CSharpGenerator(); 27 | string code = csgenerator.GenerateCode(schema); 28 | Console.WriteLine(code); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CommandLineGenerator/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("WebGenerator")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("WebGenerator")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("efc0d679-d718-4391-a6f2-bd63ec109e35")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Fsg.peg: -------------------------------------------------------------------------------- 1 | <> 7 | 8 | ^^bfschema: S byteorder? S datablocks S (!./FATAL<"Expected end of file">); 9 | 10 | S: (whitespace / comment)*; 11 | whitespace: [ \t\r\n]; 12 | 13 | comment: singleline_comment / multiline_comment; 14 | singleline_comment: '//' [^#x000D#x000A#x0085#x2028#x2029]*; 15 | multiline_comment: '/*' ( !'*/' . )* '*/'; 16 | 17 | valid_item_name: [_a-zA-Z][_a-zA-Z0-9]*; 18 | 19 | ^^byteorder: 'byteOrdering' S @'::' S ( littleendian / bigendian / FATAL<"'little-endian' or 'big-endian' expected."> ) S @';'; 20 | ^^littleendian: 'little-endian'; 21 | ^^bigendian: 'big-endian'; 22 | ^^skip: 'skip' S; 23 | ^^conditional: 'if' S '(' S expression S ')' S; 24 | 25 | ^^formatspecifier: 'format'; 26 | datablocks: (datablock S)+ / FATAL<"Datablock expected">; 27 | datablock: (struct / rel_offset / abs_offset / enum / bitfield) S; 28 | ^^field: skip? conditional? fieldname S '::' S type @';'; 29 | ^^localfield: 'local' S @fieldname S @'::' S @primitivetype S localassignment? @';'; 30 | localassignment: '=' S expression S; 31 | ^^type: (primitivetype / functiontype / namedtype / FATAL<"primitive, named or function type expected">) S (arrayknown / arrayunknown)? S; 32 | ^^primitivetype: 'bool' / 'sbyte' / 'ubyte' / 'short' / 'ushort' / 'int' / 'uint' / 'long' / 'ulong'; 33 | ^^namedtype: valid_item_name; 34 | ^^functiontype: functionname S '(' S @string S ')' S; 35 | ^^functionname: valid_item_name; 36 | 37 | ^^action_list: '[' S (actions / FATAL<"Empty action list">) S @']' S; 38 | actions: action (',' S actions )?; 39 | action: assignment / output; 40 | ^^assignment: varname S '=' S @expression S; 41 | ^^output: ^('warning'/'error'/'debug') S @'(' S @string S @')' S; 42 | 43 | ^^blockname: valid_item_name; 44 | 45 | ^^string: '"' ( !'"' . )* '"'; 46 | ^^hex: '0x' hexbyte+; 47 | hexbyte: [0-9A-Fa-f] ([0-9A-Fa-f] / FATAL<"Two hex chars required per byte.">); 48 | ^^EOF: 'EOF'; 49 | 50 | ^^fieldname: valid_item_name; 51 | 52 | ^^arrayknown: '[' expression @']'; 53 | ^^arrayunknown: '[' S ']' S ^'until' S stoplist S; 54 | 55 | stoplist: stopcase S (or_keyword S stoplist S )? S; 56 | ^or_keyword: 'or'; 57 | ^^stopcase: ( stopword S inclusion? S) / EOF / FATAL<"Hex, string or EOF expected">; 58 | stopword: string / hex; 59 | ^^inclusion: 'included' / 'excluded' / 'skipped'; 60 | 61 | ^^struct: formatspecifier? S ^'struct' S @blockname S compression? S @'{' S (localfield S)* (field S)+ @'}' S; 62 | ^^rel_offset: formatspecifier? S ^'rel_offset' S @blockname S compression? S '::' S @primitivetype S @'{' S (localfield S)* (field S)+ @'}' S; 63 | ^^abs_offset: formatspecifier? S ^'abs_offset' S @blockname S compression? S '::' S @primitivetype S @'{' S (localfield S)* (field S)+ @'}' S; 64 | ^^enum: formatspecifier? S ^'enum' S @blockname S '::' S @primitivetype S @'{' S (localfield S)* (enumfield S)+ @'}' S; 65 | ^^bitfield: formatspecifier? S ^'bitfield' S @blockname S '::' S @primitivetype S @'{' S (localfield S)* (bit S)+ @'}' S; 66 | 67 | compression: '<' S compressionmethod S '>'; 68 | ^^compressionmethod: valid_item_name; 69 | 70 | ^^enumfield: ( number / enumrange / else ) S nameoractions? @';'; 71 | ^^else: 'else'; 72 | ^^enumrange: ^('['/']') S @number S @'..' S @number S ^('['/']'); 73 | ^^enumname: valid_item_name; 74 | nameoractions: ':' S enumname? S action_list? S; 75 | 76 | ^^bitname: valid_item_name; 77 | ^^bit: number S (':' S bitname? S action_list?)? @';'; 78 | 79 | ^^expression: S logical; 80 | ^logical: bitwise (^('&&'/'||') S @bitwise)*; 81 | ^bitwise: comp (^('^'/'&'/ ('|' !'|')) S @comp)*; 82 | ^comp: shift (^('!='/'=='/'<='/'>='/'<'/'>') S @shift)*; 83 | ^shift: sum (^('>>'/'<<') S @sum)*; 84 | ^sum: prod (^[+-] S @prod)*; 85 | ^prod: value (^[*/%] S @value)*; 86 | 87 | value: ( number / '(' S logical S @')' S / call / named_value ) S; 88 | ^call: invoke_name S '(' S @(^valid_item_name) S @')' S; 89 | ^number: [0-9]+; 90 | ^invoke_name: valid_item_name; 91 | ^^named_value: namelist; 92 | namelist: varname ('.' namelist )?; 93 | ^varname: valid_item_name; 94 | 95 | <> 96 | -------------------------------------------------------------------------------- /PegBase/PEG Base.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {9913580D-1543-40D5-B463-14C95BF3120C} 9 | Library 10 | Properties 11 | PegBase 12 | PegBase 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 3.5 37 | 38 | 39 | 3.5 40 | 41 | 42 | 3.5 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 59 | -------------------------------------------------------------------------------- /PegBase/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PegBase")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PegBase")] 13 | [assembly: AssemblyCopyright("Copyright © 2008")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c6a9f918-cf4b-439a-a3eb-c7ed1c723599")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /PegBase/Properties/vssver2.scc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/PegBase/Properties/vssver2.scc -------------------------------------------------------------------------------- /PegBase/vssver2.scc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andos/BinaryFileSchema/36febd8a118bd2f2a7c552f954d207459165bfc2/PegBase/vssver2.scc -------------------------------------------------------------------------------- /Phases.txt: -------------------------------------------------------------------------------- 1 |  2 | Parser+Weeder 3 | ============= 4 | * Convert parser-AST into manageble AST. 5 | 6 | Environments 7 | ============ 8 | General: 9 | -------- 10 | * Check that only one block is declared 'format'. 11 | * Check that no two blocks have the same name. 12 | * Build map of named types to their AST object. 13 | * Check that no local variables are named "value" as it is reserved. 14 | 15 | Structs: 16 | -------- 17 | * Check that no two struct fields in the same block have the same name. 18 | * Check that no local variables have the same name as local variables. 19 | * Check that no struct variables are named "value" as it is reserved. 20 | 21 | Check that only supported compressions methods are defined 22 | Check that no ascii stop cases are empty strings + trim their quotes 23 | 24 | 25 | Enums: 26 | ------ 27 | * Check that no numbers or ranges intersect. 28 | * Check that there is only one 'else'. 29 | * Check that start-range isn't bigger than end-range 30 | * Check that the exclusion of the range isn't empty or of size 1 (ex.: ]0..1[, [0..1[ ) 31 | * Build map over the enum aliases (string -> BfsEnumFieldAlias) 32 | 33 | Bitfields: 34 | ---------- 35 | * Check that no bit-indexes are listed twice. 36 | * Check that no bit-names are listed twice. 37 | * Check that the bit-indexes doesn't exeed the size of the primitive type. 38 | 39 | 40 | TypeLinking 41 | =========== 42 | * Link all unresolved field-types to their declarations (data-blocks). 43 | * Link all assignment actions to their local variable (BfsActionUnresolvedAssignment -> BfsActionAssignment) 44 | 45 | 46 | Hierarchy 47 | ========= 48 | * Resolve all unresolved expression variables into a BFSExpressionVariable hiearchy. 49 | * Check that the variables exists in the hiearchy structure (ex. "a.b.c" that b exists in a and c exists in b) 50 | (postponed) Check that there are no circular references of struct-types unless there are conditionals. 51 | * Make map of all dependant variables at the root of Expressions (for Definite Assignment) 52 | 53 | * Check that 'value' expressions values are only used in consumed types. 54 | * Check that the argument in a 'sizeof()' call is a datablock type. 55 | 56 | * Check that BFSExpressionEnumName are only used in an equals '==' or not equal '!=' comparisson 57 | + that it is compared against a variable of enum-type. 58 | 59 | * Check that no unknown sized arrays are located within any structure that is compressed (seeking not allowed) 60 | 61 | Check the above case but indirect structs (if any non-compressed structs are contained within a compressed struct, it is also compressed) 62 | 63 | TypeChecking 64 | ============ 65 | * Resolve the type of all expressions. 66 | * Check that the type of conditionals have the type 'bool'. 67 | * Check that the types of the expressions match the type they are assigned to. 68 | * Check that known array extension expressions are of type bigger than bool. 69 | * Check that the expressions are of a boolean type, primitive type or ConsumedType (which is a primitive type). 70 | * Check that no part of expression values are of a type with an array extension. 71 | * Check that no functon types (ascii ect) are used in expressions. 72 | 73 | DefiniteAssignment 74 | ================== 75 | * Check that local-fields aren't used in their own intialization expression. 76 | * Check that struct-fields aren't used in their own conditional expression. 77 | * Check that no variables in conditional expressions or known array expressions aren't read from the file yet. 78 | * Check that no struct fields come after an unknown array extension only terminating at EOF (unreachable) 79 | * Check that no stopcases comes after an EOF (give warning) 80 | 81 | Check that all local variables are assigned to before use. 82 | 83 | * Perform a topological sort of dependencies in local variables to find out 84 | if a value is used before it is read from the file as well as when the value 85 | should be assigned to in the parsing process. 86 | 87 | CodeGeneration 88 | ============== 89 | 90 | Generate a class for each datablock in the schema with it's name. 91 | Make a check that abs_offset and rel_offset values doesn't read from offset 0. 92 | 93 | 94 | Future prospects 95 | ================ 96 | 97 | String datatype (ascii/utf8/utf16/utf32/python) for types and expressions (can compare) 98 | Constant datatypes for int() long() - fx. expecting a piece of data interpreted as long(42) 99 | Give parameters into structs: var :: type(param)[arrExt]; 100 | - useful for passing on sizes of internal arrays and such. 101 | - Probably needs revision of ascii("hello") syntax into ascii["hello"]. 102 | 103 | 104 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Binary File Schema 2 | ================== 3 | 4 | http://www.andersriggelsen.dk/binaryfileschema.php 5 | 6 | Executable file here: 7 | http://www.andersriggelsen.dk/files/fileschema/BinaryFileSchemaGUI.zip 8 | 9 | Binary File Schemas is a project of mine that will allow you to define the structure of various binary files. 10 | There are quite a lot of uses for this: 11 | 12 | * Easy to explain the structure of binary files to other people 13 | * Create programs that can inspect any binary file given a schema 14 | * Automatically generate a parser directly from a schema 15 | * Extend application functionality (eg. allow Google Desktop Search to search virtually any file if you have schemas for them) 16 | * Make compression/diff programs content-aware to maximize speed and accuracy. 17 | * Binary File Schemas' syntax include basic validation and computation functionality. 18 | 19 | Features so far 20 | --------------- 21 | * Structures - ordered list of data 22 | * Offset structures - data stored at other places at either relative or absolute offsets to the read value 23 | * Enums - limited set of possible values 24 | * Bitfields - fields containing a bunch of flags 25 | * Arrays - of both constant, calculated and unknown lengths (with multiple stop clauses) 26 | * Compression - Automatically handles compressed structures of data (C# generator supports GZip and Deflate) 27 | 28 | The aim is not to be able to express all kinds of binary files but at least attempt to express most types of formats in a simple syntax. 29 | 30 | Credits: 31 | -------- 32 | Parsing Expression Grammar generator: 33 | http://www.codeproject.com/Articles/29713/Parsing-Expression-Grammar-Support-for-C-3-0-Part 34 | 35 | Silk icons for the GUI: 36 | http://www.famfamfam.com/lab/icons/silk/ 37 | -------------------------------------------------------------------------------- /TestFileGenerator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.IO.Compression; 4 | 5 | namespace TestFileGenerator 6 | { 7 | class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | //The purpose of this test project is simply to generate a simple text file that gets compressed using GZip 12 | 13 | byte[] charName = new byte[] { (byte)'A', (byte)'n', (byte)'d', (byte)'e', (byte)'r', (byte)'s', (byte)' ', 14 | (byte)'R', (byte)'i', (byte)'g', (byte)'g', (byte)'e', (byte)'l', (byte)'s', (byte)'e', (byte)'n' }; 15 | 16 | FileStream outfile = new FileStream("compressed.dat", FileMode.Create); 17 | GZipStream gzipCompressor = new GZipStream(outfile, CompressionMode.Compress); 18 | gzipCompressor.Write(charName, 0, charName.Length); 19 | 20 | gzipCompressor.Close(); 21 | outfile.Close(); 22 | 23 | FileStream infile = new FileStream("compressed.dat", FileMode.Open); 24 | outfile = new FileStream("decompressed.txt", FileMode.Create); 25 | GZipStream gzipDecompressor = new GZipStream(infile, CompressionMode.Decompress); 26 | byte[] readBuffer = new byte[1000]; 27 | int count = gzipDecompressor.Read(readBuffer, 0, 1000); 28 | outfile.Write(readBuffer, 0, count); 29 | infile.Close(); 30 | outfile.Close(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /TestFileGenerator/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TestFileGenerator")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("TestFileGenerator")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f9a4542f-7954-4766-8a32-51b5359037e2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /TestFileGenerator/TestFileGenerator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {6ADA732D-754B-41B7-8C87-033153BBF6B1} 9 | Exe 10 | Properties 11 | TestFileGenerator 12 | TestFileGenerator 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 3.5 37 | 38 | 39 | 3.5 40 | 41 | 42 | 3.5 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 59 | --------------------------------------------------------------------------------