Full Code of jglim/CaesarSuite for AI

main f8e8463f94aa cached
110 files
1.1 MB
345.4k tokens
634 symbols
1 requests
Download .txt
Showing preview only (1,189K chars total). Download the full file or copy to clipboard to get everything.
Repository: jglim/CaesarSuite
Branch: main
Commit: f8e8463f94aa
Files: 110
Total size: 1.1 MB

Directory structure:
gitextract_yphdzm_6/

├── .gitignore
├── Caesar/
│   ├── Caesar/
│   │   ├── App.config
│   │   ├── BitUtility.cs
│   │   ├── CFFHeader.cs
│   │   ├── CTFHeader.cs
│   │   ├── CTFLanguage.cs
│   │   ├── Caesar.csproj
│   │   ├── CaesarContainer.cs
│   │   ├── CaesarReader.cs
│   │   ├── CaesarStructure.cs
│   │   ├── ComParameter.cs
│   │   ├── DSCContext.cs
│   │   ├── DTC.cs
│   │   ├── DiagPreparation.cs
│   │   ├── DiagPresentation.cs
│   │   ├── DiagService.cs
│   │   ├── ECU.cs
│   │   ├── ECUInterface.cs
│   │   ├── ECUInterfaceSubtype.cs
│   │   ├── ECUVariant.cs
│   │   ├── ECUVariantPattern.cs
│   │   ├── Flash/
│   │   │   ├── CaesarFlashContainer.cs
│   │   │   ├── FlashDataBlock.cs
│   │   │   ├── FlashDescriptionHeader.cs
│   │   │   ├── FlashHeader.cs
│   │   │   ├── FlashSecurity.cs
│   │   │   └── FlashSegment.cs
│   │   ├── Program.cs
│   │   ├── Properties/
│   │   │   └── AssemblyInfo.cs
│   │   ├── Scale.cs
│   │   ├── StubHeader.cs
│   │   ├── VCDomain.cs
│   │   ├── VCFragment.cs
│   │   ├── VCSubfragment.cs
│   │   └── packages.config
│   ├── Caesar.sln
│   ├── Diogenes/
│   │   ├── App.config
│   │   ├── DiagnosticProtocol/
│   │   │   ├── BaseProtocol.cs
│   │   │   ├── KW2C3PE.cs
│   │   │   ├── UDS.cs
│   │   │   └── UnsupportedProtocol.cs
│   │   ├── Diogenes.csproj
│   │   ├── ECUConnection.cs
│   │   ├── ECUFlashMetadata.cs
│   │   ├── ECUIdentification.cs
│   │   ├── ECUMetadata.cs
│   │   ├── Forms/
│   │   │   ├── AboutForm.Designer.cs
│   │   │   ├── AboutForm.cs
│   │   │   ├── AboutForm.resx
│   │   │   ├── BlockDownload.Designer.cs
│   │   │   ├── BlockDownload.cs
│   │   │   ├── BlockDownload.resx
│   │   │   ├── DTCForm.Designer.cs
│   │   │   ├── DTCForm.cs
│   │   │   ├── DTCForm.resx
│   │   │   ├── FlashSplicer.Designer.cs
│   │   │   ├── FlashSplicer.cs
│   │   │   ├── FlashSplicer.resx
│   │   │   ├── GenericLoader.Designer.cs
│   │   │   ├── GenericLoader.cs
│   │   │   ├── GenericLoader.resx
│   │   │   ├── GenericPicker.Designer.cs
│   │   │   ├── GenericPicker.cs
│   │   │   ├── GenericPicker.resx
│   │   │   ├── MainForm.Designer.cs
│   │   │   ├── MainForm.cs
│   │   │   ├── MainForm.resx
│   │   │   ├── PickDiagForm.Designer.cs
│   │   │   ├── PickDiagForm.cs
│   │   │   ├── PickDiagForm.resx
│   │   │   ├── RunDiagForm.Designer.cs
│   │   │   ├── RunDiagForm.cs
│   │   │   ├── RunDiagForm.resx
│   │   │   ├── SecurityLevelForm.Designer.cs
│   │   │   ├── SecurityLevelForm.cs
│   │   │   ├── SecurityLevelForm.resx
│   │   │   ├── TraceForm.Designer.cs
│   │   │   ├── TraceForm.cs
│   │   │   ├── TraceForm.resx
│   │   │   ├── UDSHexEditor.Designer.cs
│   │   │   ├── UDSHexEditor.cs
│   │   │   ├── UDSHexEditor.resx
│   │   │   ├── VCForm.Designer.cs
│   │   │   ├── VCForm.cs
│   │   │   └── VCForm.resx
│   │   ├── Preferences.cs
│   │   ├── Program.cs
│   │   ├── Properties/
│   │   │   ├── AssemblyInfo.cs
│   │   │   ├── Resources.Designer.cs
│   │   │   ├── Resources.resx
│   │   │   ├── Settings.Designer.cs
│   │   │   └── Settings.settings
│   │   ├── Reports/
│   │   │   ├── DTCReport.cs
│   │   │   └── VCReport.cs
│   │   ├── SecurityAccess/
│   │   │   ├── DllContext.cs
│   │   │   ├── ExportDefinition.cs
│   │   │   └── SecurityAutoLogin.cs
│   │   ├── Simulation/
│   │   │   ├── SimulatedDevice.cs
│   │   │   └── Simulated_CRD3.cs
│   │   ├── TextboxWriter.cs
│   │   ├── UnmanagedUtility.cs
│   │   ├── VariantCoding.cs
│   │   └── packages.config
│   └── Trafo/
│       ├── App.config
│       ├── Program.cs
│       ├── Properties/
│       │   └── AssemblyInfo.cs
│       ├── Trafo.csproj
│       └── packages.config
├── LICENSE
└── README.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Mono auto generated files
mono_crash.*

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/

# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# Visual Studio 2017 auto generated files
Generated\ Files/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# Benchmark Results
BenchmarkDotNet.Artifacts/

# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/

# StyleCop
StyleCopReport.xml

# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# Visual Studio Trace Files
*.e2e

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json

# Visual Studio code coverage results
*.coverage
*.coveragexml

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs

# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak

# SQL Server files
*.mdf
*.ldf
*.ndf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# CodeRush personal settings
.cr/personal

# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config

# Tabs Studio
*.tss

# Telerik's JustMock configuration file
*.jmconfig

# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs

# OpenCover UI analysis results
OpenCover/

# Azure Stream Analytics local run output
ASALocalRun/

# MSBuild Binary and Structured Log
*.binlog

# NVidia Nsight GPU debugger configuration file
*.nvuser

# MFractors (Xamarin productivity tool) working folder
.mfractor/

# Local History for Visual Studio
.localhistory/

# BeatPulse healthcheck temp database
healthchecksdb

# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/

# Ionide (cross platform F# VS Code tools) working folder
.ionide/


================================================
FILE: Caesar/Caesar/App.config
================================================
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
    </startup>
</configuration>

================================================
FILE: Caesar/Caesar/BitUtility.cs
================================================
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Caesar
{
    /// <summary>
    /// Utilities for bit and byte operations.
    /// (Frequently copied-and-pasted across my projects)
    /// </summary>
    public class BitUtility
    {
        /// <summary>
        /// Sets all values in an array of bytes to a specific value
        /// </summary>
        /// <param name="value">Value to set byte array to</param>
        /// <param name="buf">Target byte array buffer</param>
        public static void Memset(byte value, byte[] buf)
        {
            for (int i = 0; i < buf.Length; i++)
            {
                buf[i] = value;
            }
        }
        // Internally used by BytesFromHex
        private static byte[] StringToByteArrayFastest(string hex)
        {
            // see https://stackoverflow.com/questions/321370/how-can-i-convert-a-hex-string-to-a-byte-array
            if (hex.Length % 2 == 1)
            {
                throw new Exception("The binary key cannot have an odd number of digits");
            }
            byte[] arr = new byte[hex.Length >> 1];
            for (int i = 0; i < hex.Length >> 1; ++i)
            {
                arr[i] = (byte)((GetHexValue(hex[i << 1]) << 4) + (GetHexValue(hex[(i << 1) + 1])));
            }
            return arr;
        }
        // Internally used by StringToByteArrayFastest
        private static int GetHexValue(char hex)
        {
            int val = (int)hex;
            return val - (val < 58 ? 48 : 55);
        }
        /// <summary>
        /// Converts an array of bytes into its hex-string equivalent
        /// </summary>
        /// <param name="inBytes">Input byte array</param>
        /// <param name="spacedOut">Option to add spaces between individual bytes</param>
        /// <returns>Hex-string based on the input byte array</returns>
        public static string BytesToHex(byte[] inBytes, bool spacedOut = false)
        {
            return BitConverter.ToString(inBytes).Replace("-", spacedOut ? " " : "");
        }

        /// <summary>
        /// Converts an array of bytes into a printable hex-string
        /// </summary>
        /// <param name="hexString">Input hex-string to convert into a byte array</param>
        /// <returns>Byte array based on the input hex-string</returns>
        public static byte[] BytesFromHex(string hexString)
        {
            return StringToByteArrayFastest(hexString.Replace(" ", ""));
        }

        /// <summary>
        /// Resize a smaller array of bytes to a larger array. The padding bytes will be 0.
        /// </summary>
        /// <param name="inData">Input byte array</param>
        /// <param name="finalSize">New size for the input array</param>
        /// <returns>Resized byte array</returns>
        public static byte[] PadBytes(byte[] inData, int finalSize)
        {
            if (inData.Length > finalSize)
            {
                return inData;
            }
            byte[] result = new byte[finalSize];
            Buffer.BlockCopy(inData, 0, result, 0, inData.Length);
            return result;
        }

        [StructLayout(LayoutKind.Explicit)]
        struct UIntFloat
        {
            [FieldOffset(0)]
            public float FloatValue;

            [FieldOffset(0)]
            public uint IntValue;
        }

        /// <summary>
        /// Directly converts an in-memory representation of an uint to a float.
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static float ToFloat(uint value)
        {
            UIntFloat intermediate = new UIntFloat();
            intermediate.IntValue = value;
            return intermediate.FloatValue;
        }


        // Caesar specific

        public static byte[] BitArrayToByteArray(byte[] inArray, bool littleEndian = true)
        {
            if (inArray.Length % 8 != 0)
            {
                throw new NotImplementedException("Bits must be byte-aligned");
            }

            byte[] result = new byte[inArray.Length / 8];
            byte workingByte = 0;
            int arrayIndex = 0;
            for (int i = 0; i < inArray.Length; i++)
            {
                if (littleEndian)
                {
                    workingByte >>= 1;
                    workingByte |= (inArray[i] == 0) ? (byte)0 : (byte)0x80;
                }
                else
                {
                    workingByte <<= 1;
                    workingByte |= inArray[i];
                }
                if (i % 8 == 7)
                {
                    result[arrayIndex] = workingByte;
                    arrayIndex++;
                }
            }
            return result;
        }

        public static byte[] ByteArrayToBitArray(byte[] inArray, bool littleEndian = true)
        {
            byte[] result = new byte[inArray.Length * 8];
            int arrayIndex = 0;
            foreach (byte inByte in inArray)
            {
                if (littleEndian)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        bool bitSet = ((1 << i) & inByte) > 0;
                        result[arrayIndex] = (bitSet ? (byte)1 : (byte)0);
                        arrayIndex++;
                    }
                }
                else
                {
                    for (int i = 7; i >= 0; i--)
                    {
                        bool bitSet = ((1 << i) & inByte) > 0;
                        result[arrayIndex] = (bitSet ? (byte)1 : (byte)0);
                        arrayIndex++;
                    }
                }
            }
            return result;
        }

        public static string BytesToBitString(byte[] inArray)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte b in inArray)
            {
                sb.Append(Convert.ToString(b, toBase: 2).PadLeft(8, '0') + " ");
            }
            return sb.ToString().TrimEnd();
        }
        public static string BytesToDecimalString(byte[] inArray)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte b in inArray)
            {
                sb.Append(Convert.ToString(b, toBase: 10).PadLeft(3, '0') + " ");
            }
            return sb.ToString().TrimEnd();
        }
        public static byte[] BytesFromDecimalString(string inData)
        {
            string[] chunks = inData.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
            byte[] result = new byte[chunks.Length];
            for (int i = 0; i < chunks.Length; i++) 
            {
                result[i] = byte.Parse(chunks[i]);
            }
            return result;
        }

        public static string BitsToString(byte[] inArray) 
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < inArray.Length; i++)
            {
                sb.Append(inArray[i]);
                if (i % 8 == 7) 
                {
                    sb.Append(" ");
                }
            }
            return sb.ToString();
        }

        public void BitRoundtripTest() 
        {
            byte[] bitarray = new byte[] {
                1,1,1,1, 1,1,1,1,
                1,0,1,0, 1,0,1,0,
                0,1,0,1, 0,1,0,1,
                0,0,0,0, 0,0,0,0,
                1,1,1,1, 0,0,0,0,
                0,0,0,0, 1,1,1,1,
            };
            byte[] testByteArray = BitUtility.BitArrayToByteArray(bitarray, false);
            Console.WriteLine($"test in 1: {BitUtility.BytesToBitString(testByteArray)}");
            Console.WriteLine($"test in 1: {BitUtility.BytesToHex(testByteArray)}");
            foreach (byte b in bitarray)
            {
                Console.Write(b);
            }
            Console.WriteLine();

            byte[] testBitArray = BitUtility.ByteArrayToBitArray(testByteArray, false);
            testByteArray = BitUtility.BitArrayToByteArray(testBitArray);
            Console.WriteLine($"test in 2: {BitUtility.BytesToBitString(testByteArray)}");
            Console.WriteLine($"test in 2: {BitUtility.BytesToHex(testByteArray)}");

            foreach (byte b in testBitArray)
            {
                Console.Write(b);
            }
            Console.WriteLine();

        }

        public static bool CheckHexValid(string inHex) 
        {
            string cleanedText = inHex.Replace(" ", "").Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace("-", "").ToUpper();
            if (cleanedText.Length % 2 != 0)
            {
                return false;
            }
            if (!System.Text.RegularExpressions.Regex.IsMatch(cleanedText, @"\A\b[0-9a-fA-F]+\b\Z"))
            {
                return false;
            }
            return true;
        }
    }
}


================================================
FILE: Caesar/Caesar/CFFHeader.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Caesar
{
    public class CFFHeader
    {
        public int CaesarVersion;
        public int GpdVersion;
        public int EcuCount;
        public int EcuOffset;
        public int CtfOffset; // nCtfHeaderRpos
        public int StringPoolSize;
        private int DscOffset;
        private int DscCount;
        private int DscEntrySize;
        public string CbfVersionString;
        public string GpdVersionString;
        public string XmlString;

        [Newtonsoft.Json.JsonIgnore]
        public int CffHeaderSize;
        [Newtonsoft.Json.JsonIgnore]
        public long BaseAddress;

        public long DscBlockOffset;
        private int DscBlockSize;

        [Newtonsoft.Json.JsonIgnore]
        public byte[] DSCPool = new byte[] { };

        // DIIAddCBFFile

        public CFFHeader() 
        { }

        public CFFHeader(BinaryReader reader) 
        {
            reader.BaseStream.Seek(StubHeader.StubHeaderSize, SeekOrigin.Begin);
            CffHeaderSize = reader.ReadInt32();

            BaseAddress = reader.BaseStream.Position;

            ulong bitFlags = reader.ReadUInt16();

            CaesarVersion = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            GpdVersion = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            EcuCount = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            EcuOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            CtfOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            StringPoolSize = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            DscOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            DscCount = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            DscEntrySize = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);

            CbfVersionString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);
            GpdVersionString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);
            XmlString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);

            
            long dataBufferOffsetAfterStrings = StringPoolSize + CffHeaderSize + 0x414;
            if (DscCount > 0) 
            {
                DscBlockOffset = DscOffset + dataBufferOffsetAfterStrings;
                DscBlockSize = DscEntrySize * DscCount;
                reader.BaseStream.Seek(DscBlockOffset, SeekOrigin.Begin);
                DSCPool = reader.ReadBytes(DscBlockSize);
            }
        }

        public void PrintDebug() 
        {
            Console.WriteLine($"{nameof(CaesarVersion)} : {CaesarVersion}");
            Console.WriteLine($"{nameof(GpdVersion)} : {GpdVersion}");
            Console.WriteLine($"{nameof(EcuCount)} : {EcuCount}");
            Console.WriteLine($"{nameof(EcuOffset)} : {EcuOffset} 0x{EcuOffset:X}");
            Console.WriteLine($"{nameof(CtfOffset)} : 0x{CtfOffset:X}");
            Console.WriteLine($"{nameof(StringPoolSize)} : {StringPoolSize} 0x{StringPoolSize:X}");
            
            Console.WriteLine($"{nameof(DscEntrySize)} : {DscEntrySize}");
            Console.WriteLine($"{nameof(CbfVersionString)} : {CbfVersionString}");
            Console.WriteLine($"{nameof(GpdVersionString)} : {GpdVersionString}");

            Console.WriteLine($"{nameof(DscOffset)} : {DscOffset} 0x{DscOffset:X}");
            Console.WriteLine($"{nameof(DscBlockOffset)} : {DscBlockOffset} 0x{DscBlockOffset:X}");
            Console.WriteLine($"{nameof(DscCount)} : {DscCount}");
            Console.WriteLine($"{nameof(DscBlockSize)} : {DscCount}");
        }
    }
}


================================================
FILE: Caesar/Caesar/CTFHeader.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Caesar
{
    public class CTFHeader
    {
        public int CtfUnk1;
        public string Qualifier;
        public int CtfUnk3;
        public int CtfUnk4;
        private int CtfLanguageCount;
        private int CtfLanguageTableOffset;
        public string CtfUnkString;

        public List<CTFLanguage> CtfLanguages;

        public long BaseAddress;

        public CTFHeader() { }
        public CTFHeader(BinaryReader reader, long baseAddress, int headerSize) 
        {
            BaseAddress = baseAddress;
            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);
            ulong ctfBitflags = reader.ReadUInt16();

            CtfUnk1 = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader);
            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref ctfBitflags, reader, BaseAddress);
            CtfUnk3 = CaesarReader.ReadBitflagInt16(ref ctfBitflags, reader);
            CtfUnk4 = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader);
            CtfLanguageCount = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader);
            CtfLanguageTableOffset = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader);
            CtfUnkString = CaesarReader.ReadBitflagStringWithReader(ref ctfBitflags, reader, BaseAddress);

            long ctfLanguageTableOffsetRelativeToDefintions = CtfLanguageTableOffset + BaseAddress;

            // parse every language record
            CtfLanguages = new List<CTFLanguage>();
            for (int languageEntry = 0; languageEntry < CtfLanguageCount; languageEntry++)
            {
                long languageTableEntryOffset = ctfLanguageTableOffsetRelativeToDefintions + (languageEntry * 4);

                reader.BaseStream.Seek(languageTableEntryOffset, SeekOrigin.Begin);
                long realLanguageEntryAddress = reader.ReadInt32() + ctfLanguageTableOffsetRelativeToDefintions;
                CTFLanguage language = new CTFLanguage(reader, realLanguageEntryAddress, headerSize);
                CtfLanguages.Add(language);
            }
        }
        public void PrintDebug() 
        {
            Console.WriteLine("----------- CTF header ----------- ");
            Console.WriteLine($"{nameof(CtfUnk1)} : {CtfUnk1}");
            Console.WriteLine($"{nameof(Qualifier)} : {Qualifier}");
            Console.WriteLine($"{nameof(CtfUnk3)} : {CtfUnk3}");
            Console.WriteLine($"{nameof(CtfUnk4)} : {CtfUnk4}");
            Console.WriteLine($"{nameof(CtfLanguageCount)} : {CtfLanguageCount}");
            Console.WriteLine($"{nameof(CtfLanguageTableOffset)} : 0x{CtfLanguageTableOffset:X}");
            Console.WriteLine($"{nameof(CtfUnkString)} : {CtfUnkString}");
        }
    }
}


================================================
FILE: Caesar/Caesar/CTFLanguage.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Caesar
{
    public class CTFLanguage
    {
        public string Qualifier;
        public int LanguageIndex;
        private int StringPoolSize;
        private int MaybeOffsetFromStringPoolBase;
        private int StringCount;
        public List<string> StringEntries;

        public long BaseAddress;
        public CTFLanguage() { }
        public CTFLanguage(BinaryReader reader, long baseAddress, int headerSize) 
        {
            BaseAddress = baseAddress;
            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);
            ulong languageEntryBitflags = reader.ReadUInt16();

            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref languageEntryBitflags, reader, BaseAddress);
            LanguageIndex = CaesarReader.ReadBitflagInt16(ref languageEntryBitflags, reader);
            StringPoolSize = CaesarReader.ReadBitflagInt32(ref languageEntryBitflags, reader);
            MaybeOffsetFromStringPoolBase = CaesarReader.ReadBitflagInt32(ref languageEntryBitflags, reader);
            StringCount = CaesarReader.ReadBitflagInt32(ref languageEntryBitflags, reader);

            LoadStrings(reader, headerSize, CaesarReader.DefaultEncoding);
        }

        public void LoadStrings(BinaryReader reader, int headerSize, Encoding encoding) 
        {
            StringEntries = new List<string>();
            int caesarStringTableOffset = headerSize + 0x410 + 4; // header.CffHeaderSize; strange that this has to be manually computed
            for (int i = 0; i < StringCount; i++) 
            {
                reader.BaseStream.Seek(caesarStringTableOffset + (i * 4), SeekOrigin.Begin);
                int stringOffset = reader.ReadInt32();
                reader.BaseStream.Seek(caesarStringTableOffset + stringOffset, SeekOrigin.Begin);
                string result = CaesarReader.ReadStringFromBinaryReader(reader, encoding);
                StringEntries.Add(result);
            }
        }

        public string GetString(int stringId) 
        {
            return GetString(StringEntries, stringId);
        }

        public static string GetString(List<string> language, int stringId) 
        {
            if (stringId < 0) 
            {
                return "";
            }
            if (stringId > language.Count) 
            {
                return "";
            }
            return language[stringId];
        }

        public void PrintDebug() 
        {
            Console.WriteLine($"Language: {Qualifier} stringCount: {StringCount} stringPoolSize 0x{StringPoolSize:X}, unknowns: {LanguageIndex} {MaybeOffsetFromStringPoolBase}, base: {BaseAddress:X} ");
        }
    }
}


================================================
FILE: Caesar/Caesar/Caesar.csproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{71C43C61-7DC7-4D47-9947-1DD73E559911}</ProjectGuid>
    <OutputType>Library</OutputType>
    <RootNamespace>Caesar</RootNamespace>
    <AssemblyName>Caesar</AssemblyName>
    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <Deterministic>true</Deterministic>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
  </PropertyGroup>
  <PropertyGroup>
    <StartupObject />
  </PropertyGroup>
  <PropertyGroup>
    <ApplicationIcon>caesar_256.ico</ApplicationIcon>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
      <HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="BitUtility.cs" />
    <Compile Include="CaesarContainer.cs" />
    <Compile Include="DiagPresentation.cs" />
    <Compile Include="DTC.cs" />
    <Compile Include="Flash\CaesarFlashContainer.cs" />
    <Compile Include="CaesarReader.cs" />
    <Compile Include="CaesarStructure.cs" />
    <Compile Include="CFFHeader.cs" />
    <Compile Include="ComParameter.cs" />
    <Compile Include="CTFHeader.cs" />
    <Compile Include="CTFLanguage.cs" />
    <Compile Include="DiagPreparation.cs" />
    <Compile Include="DiagService.cs" />
    <Compile Include="DSCContext.cs" />
    <Compile Include="ECU.cs" />
    <Compile Include="ECUInterface.cs" />
    <Compile Include="ECUInterfaceSubtype.cs" />
    <Compile Include="ECUVariant.cs" />
    <Compile Include="ECUVariantPattern.cs" />
    <Compile Include="Flash\FlashDataBlock.cs" />
    <Compile Include="Flash\FlashDescriptionHeader.cs" />
    <Compile Include="Flash\FlashHeader.cs" />
    <Compile Include="Flash\FlashSecurity.cs" />
    <Compile Include="Flash\FlashSegment.cs" />
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Scale.cs" />
    <Compile Include="StubHeader.cs" />
    <Compile Include="VCDomain.cs" />
    <Compile Include="VCFragment.cs" />
    <Compile Include="VCSubfragment.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config" />
    <None Include="packages.config" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="caesar_256.ico" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

================================================
FILE: Caesar/Caesar/CaesarContainer.cs
================================================
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace Caesar
{
    public class CaesarContainer
    {
        public CFFHeader CaesarCFFHeader;
        public CTFHeader CaesarCTFHeader;
        public List<ECU> CaesarECUs = new List<ECU>();
        [Newtonsoft.Json.JsonIgnore]
        public byte[] FileBytes = new byte[] { };

        public uint FileChecksum;

        public CaesarContainer() { }

        // fixup serialization/deserialization:
        // language strings should be properties; resolve to actual string only when called
        public CaesarContainer(byte[] fileBytes)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();

            FileBytes = fileBytes;
            // work from int __cdecl DIIAddCBFFile(char *fileName)
            using (BinaryReader reader = new BinaryReader(new MemoryStream(fileBytes, 0, fileBytes.Length, false, true)))
            {
                byte[] header = reader.ReadBytes(StubHeader.StubHeaderSize);
                StubHeader.ReadHeader(header);

                int cffHeaderSize = reader.ReadInt32();
                byte[] cffHeaderData = reader.ReadBytes(cffHeaderSize);

                // expensive, probably an impediment for modders
                // VerifyChecksum(fileBytes, out uint checksum);
                FileChecksum = ReadFileChecksum(fileBytes);

                ReadCFFDefinition(reader);
                // language is the highest priority since all our strings come from it
                ReadCTF(reader);
                ReadECU(reader);
            }

            sw.Stop();
#if DEBUG
            Console.WriteLine($"Loaded {CaesarECUs[0].Qualifier} in {sw.ElapsedMilliseconds}ms");
#endif
        }

        public static string SerializeContainer(CaesarContainer container) 
        {
            return JsonConvert.SerializeObject(container);
        }

        public static CaesarContainer DeserializeContainer(string json) 
        {
            CaesarContainer container = JsonConvert.DeserializeObject<CaesarContainer>(json);
            // at this point, the container needs to restore its internal object references before it is fully usable
            CTFLanguage language = container.CaesarCTFHeader.CtfLanguages[0];
            foreach (ECU ecu in container.CaesarECUs) 
            {
                ecu.Restore(language, container);
            }

            return container;
        }

        public static CaesarContainer DeserializeCompressedContainer(byte[] containerBytes)
        {
            string json = Encoding.UTF8.GetString(Inflate(containerBytes));
            return DeserializeContainer(json);
        }
        public static byte[] SerializeCompressedContainer(CaesarContainer container)
        {
            return Deflate(Encoding.UTF8.GetBytes(SerializeContainer(container)));
        }


        private static byte[] Inflate(byte[] input)
        {
            using (MemoryStream ms = new MemoryStream(input))
            {
                using (MemoryStream msInner = new MemoryStream())
                {
                    using (DeflateStream z = new DeflateStream(ms, CompressionMode.Decompress))
                    {
                        z.CopyTo(msInner);
                    }
                    return msInner.ToArray();
                }
            }
        }
        private static byte[] Deflate(byte[] input)
        {
            using (MemoryStream compressedStream = new MemoryStream())
            {
                DeflateStream deflateStream = new DeflateStream(compressedStream, CompressionLevel.Optimal, true);
                deflateStream.Write(input, 0, input.Length);
                deflateStream.Close();
                return compressedStream.ToArray();
            }
        }


        public static bool VerifyChecksum(byte[] fileBytes, out uint checksum) 
        {
            uint computedChecksum = CaesarReader.ComputeFileChecksumLazy(fileBytes);
            uint providedChecksum = ReadFileChecksum(fileBytes);
            checksum = providedChecksum;
            if (computedChecksum != providedChecksum)
            {
                Console.WriteLine($"WARNING: Checksum mismatch : computed/provided: {computedChecksum:X8}/{providedChecksum:X8}");
                return false;
            }
            return true;
        }

        public static string GetCaesarVersionString()
        {
            System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
            System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location);
            return fvi.FileVersion;
        }

        public static uint ReadFileChecksum(byte[] fileBytes) 
        {
            return BitConverter.ToUInt32(fileBytes, fileBytes.Length - 4);
        }

        public ECUVariant GetECUVariantByName(string name)
        {
            foreach (ECU ecu in CaesarECUs)
            {
                foreach (ECUVariant variant in ecu.ECUVariants)
                {
                    if (variant.Qualifier == name)
                    {
                        return variant;
                    }
                }
            }
            return null;
        }
        public ECU GetECUByName(string name)
        {
            foreach (ECU ecu in CaesarECUs)
            {
                if (ecu.Qualifier == name)
                {
                    return ecu;
                }
            }
            return null;
        }

        public string[] GetECUVariantNames() 
        {
            List<string> result = new List<string>();

            foreach (ECU ecu in CaesarECUs)
            {
                foreach (ECUVariant variant in ecu.ECUVariants)
                {
                    result.Add(variant.Qualifier);
                }
            }
            return result.ToArray();
        }

        public CTFLanguage GetLanguage() 
        {
            if (CaesarCTFHeader.CtfLanguages is null)
            {
                throw new NotImplementedException("stringtable not initialized");
            }

            if (CaesarCTFHeader.CtfLanguages.Count != 0)
            {
                return CaesarCTFHeader.CtfLanguages[0];
            }
            throw new NotImplementedException("no idea how to handle missing stringtable");
        }

        void ReadECU(BinaryReader fileReader) 
        {
            CaesarECUs = new List<ECU>();
            // read all ecu definitions
            long ecuTableOffset = CaesarCFFHeader.EcuOffset + CaesarCFFHeader.BaseAddress;
            
            for (int ecuIndex = 0; ecuIndex < CaesarCFFHeader.EcuCount; ecuIndex++)
            {
                // seek to an entry the ecu offsets table
                fileReader.BaseStream.Seek(ecuTableOffset + (ecuIndex * 4), SeekOrigin.Begin);
                // read the offset to the ecu entry, then seek to the actual address
                int offsetToActualEcuEntry = fileReader.ReadInt32();
                CaesarECUs.Add(new ECU(fileReader, GetLanguage(), CaesarCFFHeader, ecuTableOffset + offsetToActualEcuEntry, this));
            }
        }

        void ReadCTF(BinaryReader fileReader) 
        {
            // parse CTF language stuff
            // approx 0x1304 / 4 number of strings?
            if (CaesarCFFHeader.CtfOffset == 0)
            {
                throw new NotImplementedException("No idea how to handle nonexistent ctf header");
            }
            long ctfOffset = CaesarCFFHeader.BaseAddress + CaesarCFFHeader.CtfOffset;
            CaesarCTFHeader = new CTFHeader(fileReader, ctfOffset, CaesarCFFHeader.CffHeaderSize);
        }


        void ReadCFFDefinition(BinaryReader fileReader)
        {
            CaesarCFFHeader = new CFFHeader(fileReader);
            // CaesarCFFHeader.PrintDebug();

            if (CaesarCFFHeader.CaesarVersion < 400) 
            {
                throw new NotImplementedException($"Unhandled Caesar version: {CaesarCFFHeader.CaesarVersion}");
            }

            int caesarStringTableOffset = CaesarCFFHeader.CffHeaderSize + 0x410 + 4;
            int formEntryTable = caesarStringTableOffset + CaesarCFFHeader.StringPoolSize;
                
            //Console.WriteLine($"{nameof(caesarStringTableOffset)} : 0x{caesarStringTableOffset:X}");
            //Console.WriteLine($"{nameof(afterStringTableOffset)} : 0x{afterStringTableOffset:X}");

            /*
            if (CaesarCFFHeader.FormEntries > 0)
            {
                int formOffsetTable = CaesarCFFHeader.unk2RelativeOffset + formEntryTable;
                int formOffsetTableSize = CaesarCFFHeader.FormEntrySize * CaesarCFFHeader.FormEntries;
                Console.WriteLine($"after string table block (*.fm) is present: {nameof(formEntryTable)} : 0x{formEntryTable:X}\n\n");
                Console.WriteLine($"{nameof(formOffsetTable)} : 0x{formOffsetTable:X}\n\n");
                Console.WriteLine($"{nameof(formOffsetTableSize)} : 0x{formOffsetTableSize:X}\n\n");
            }
            */
        }

        public string GetFileSize() 
        {
            return BytesToString(FileBytes.Length);
        }

        private static string BytesToString(long byteCount)
        {
            string[] suf = { " B", " KB", " MB", " GB", " TB", " PB", " EB" }; //Longs run out around EB
            if (byteCount == 0)
            {
                return "0" + suf[0];
            }
            long bytes = Math.Abs(byteCount);
            int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
            double num = Math.Round(bytes / Math.Pow(1024, place), 3);
            return (Math.Sign(byteCount) * num).ToString() + suf[place];
        }

        public override bool Equals(object obj)
        {
            var container = obj as CaesarContainer;

            if (container == null) 
            {
                return false;
            }
            return this.FileChecksum == container.FileChecksum;
        }

        public override int GetHashCode()
        {
            return (int)FileChecksum;
        }

    }
}


================================================
FILE: Caesar/Caesar/CaesarReader.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Caesar
{
    public class CaesarReader
    {
        public static Encoding DefaultEncoding = Encoding.UTF8;

        // slightly more complex because it jumps to the string position for reading
        public static string ReadBitflagStringWithReader(ref ulong bitFlags, BinaryReader reader, long virtualBase = 0)
        {
            if (CheckAndAdvanceBitflag(ref bitFlags))
            {
                // read the string's offset relative to our current block
                int stringOffset = reader.ReadInt32();
                // save our reading cursor
                long readerPosition = reader.BaseStream.Position;
                // seek to the specified offset, then read out the string
                reader.BaseStream.Seek(stringOffset + virtualBase, SeekOrigin.Begin);
                string result = ReadStringFromBinaryReader(reader);
                // restore our reading cursor
                reader.BaseStream.Seek(readerPosition, SeekOrigin.Begin);
                return result;
            }
            else
            {
                // Console.WriteLine("Bitflag was off for string");
                return "(flag disabled)";
            }
        }
        public static byte[] ReadBitflagDumpWithReader(ref ulong bitFlags, BinaryReader reader, int dumpSize, long virtualBase = 0)
        {
            if (CheckAndAdvanceBitflag(ref bitFlags))
            {
                // read the dump's offset relative to our current block
                int dumpOffset = reader.ReadInt32();
                // save our reading cursor
                long readerPosition = reader.BaseStream.Position;
                // seek to the specified offset, then read out the dump
                reader.BaseStream.Seek(dumpOffset + virtualBase, SeekOrigin.Begin);
                byte[] result = reader.ReadBytes(dumpSize);
                // restore our reading cursor
                reader.BaseStream.Seek(readerPosition, SeekOrigin.Begin);
                return result;
            }
            else
            {
                return new byte[] { };
            }
        }

        public static string ReadBitflagDumpWithReaderAsString(ref ulong bitFlags, BinaryReader reader, int dumpSize, long virtualBase = 0)
        {
            byte[] stringBytes = ReadBitflagDumpWithReader(ref bitFlags, reader, dumpSize, virtualBase);
            return DefaultEncoding.GetString(stringBytes); // lazy: no encoding is specified
        }

        public static string ReadStringFromBinaryReader(BinaryReader reader, Encoding encoding = null)
        {
            if (encoding is null) 
            {
                encoding = DefaultEncoding;
            }

            // slightly better performance than the original below at the expense of compiling with unsafe
            long stringStartPosition = reader.BaseStream.Position;
            byte[] underlyingBuffer = ((MemoryStream)reader.BaseStream).GetBuffer();
            long cursor = stringStartPosition;
            while (underlyingBuffer[cursor++] != 0) 
            {
            }
            int difference = (int)(cursor - stringStartPosition) - 1;
            byte[] stringBytes = new byte[difference];
            Buffer.BlockCopy(underlyingBuffer, (int)stringStartPosition, stringBytes, 0, difference);
            return encoding.GetString(stringBytes);

            /*
            // significant performance bottleneck: (original)
            // read out a string, stopping at the first null terminator
            using (BinaryWriter writer = new BinaryWriter(new MemoryStream()))
            {
                while (true)
                {
                    byte nextByte = reader.ReadByte();
                    if (nextByte == 0)
                    {
                        byte[] stringRaw = ((MemoryStream)writer.BaseStream).ToArray();
                        return encoding.GetString(stringRaw);
                    }
                    else
                    {
                        writer.Write(nextByte);
                    }
                }
            }
            */
        }

        public static bool CheckAndAdvanceBitflag(ref ulong bitFlag)
        {
            bool flagIsSet = (bitFlag & 1) > 0;
            bitFlag >>= 1;
            return flagIsSet;
        }

        public static byte[] ReadBitflagRawBytes(ref ulong bitFlags, BinaryReader reader, int bytes) {
            if (CheckAndAdvanceBitflag(ref bitFlags)) {
                return reader.ReadBytes(bytes);
            }
            return new byte[] { };
        }
        public static float ReadBitflagFloat(ref ulong bitFlags, BinaryReader reader, float defaultResult = 0)
        {
            if (CheckAndAdvanceBitflag(ref bitFlags))
            {
                byte[] floatBytes = reader.ReadBytes(4);
                return BitConverter.ToSingle(floatBytes, 0);
            }
            return defaultResult;
        }
        public static int ReadBitflagInt32(ref ulong bitFlags, BinaryReader reader, int defaultResult = 0)
        {
            if (CheckAndAdvanceBitflag(ref bitFlags))
            {
                return reader.ReadInt32();
            }
            return defaultResult;
        }
        public static uint ReadBitflagUInt32(ref ulong bitFlags, BinaryReader reader, uint defaultResult = 0)
        {
            if (CheckAndAdvanceBitflag(ref bitFlags))
            {
                return reader.ReadUInt32();
            }
            return defaultResult;
        }
        public static short ReadBitflagInt16(ref ulong bitFlags, BinaryReader reader, short defaultResult = 0)
        {
            if (CheckAndAdvanceBitflag(ref bitFlags))
            {
                return reader.ReadInt16();
            }
            return defaultResult;
        }
        public static ushort ReadBitflagUInt16(ref ulong bitFlags, BinaryReader reader, ushort defaultResult = 0)
        {
            if (CheckAndAdvanceBitflag(ref bitFlags))
            {
                return reader.ReadUInt16();
            }
            return defaultResult;
        }
        public static int ReadBitflagInt8(ref ulong bitFlags, BinaryReader reader, int defaultResult = 0)
        {
            if (CheckAndAdvanceBitflag(ref bitFlags))
            {
                return reader.ReadChar();
            }
            return defaultResult;
        }
        public static byte ReadBitflagUInt8(ref ulong bitFlags, BinaryReader reader, byte defaultResult = 0)
        {
            if (CheckAndAdvanceBitflag(ref bitFlags))
            {
                return reader.ReadByte();
            }
            return defaultResult;
        }

        public static int ReadIntWithSize(BinaryReader reader, int size, long offset)
        {
            reader.BaseStream.Seek(offset, SeekOrigin.Begin);
            if (size == 1)
            {
                return reader.ReadChar();
            }
            else if (size == 2)
            {
                return reader.ReadInt16();
            }
            else if (size == 4)
            {
                return reader.ReadInt32();
            }
            else
            {
                throw new NotImplementedException($"Requested an unknown integer size to read: {size}");
            }
        }
        public static uint ReadUIntWithSize(BinaryReader reader, int size, long offset)
        {
            reader.BaseStream.Seek(offset, SeekOrigin.Begin);
            if (size == 1)
            {
                return reader.ReadByte();
            }
            else if (size == 2)
            {
                return reader.ReadUInt16();
            }
            else if (size == 4)
            {
                return reader.ReadUInt32();
            }
            else
            {
                throw new NotImplementedException($"Requested an unknown integer size to read: {size}");
            }
        }

        private static uint[] CrcTable = { 
            0x00000000, 0x77073096, 0x0EE0E612C, 0x990951BA, 0x76DC419, 0x706AF48F, 0x0E963A535, 0x9E6495A3, 
            0x0EDB8832, 0x79DCB8A4, 0x0E0D5E91E, 0x97D2D988, 0x9B64C2B, 0x7EB17CBD, 0x0E7B82D07, 0x90BF1D91, 
            0x1DB71064, 0x6AB020F2, 0x0F3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0x0F4D4B551, 0x83D385C7, 
            0x136C9856, 0x646BA8C0, 0x0FD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0x0FA0F3D63, 0x8D080DF5, 
            0x3B6E20C8, 0x4C69105E, 0x0D56041E4, 0x0A2677172, 0x3C03E4D1, 0x4B04D447, 0x0D20D85FD, 0x0A50AB56B, 
            0x35B5A8FA, 0x42B2986C, 0x0DBBBC9D6, 0x0ACBCF940, 0x32D86CE3, 0x45DF5C75, 0x0DCD60DCF, 0x0ABD13D59, 
            0x26D930AC, 0x51DE003A, 0x0C8D75180, 0x0BFD06116, 0x21B4F4B5, 0x56B3C423, 0x0CFBA9599, 0x0B8BDA50F, 
            0x2802B89E, 0x5F058808, 0x0C60CD9B2, 0x0B10BE924, 0x2F6F7C87, 0x58684C11, 0x0C1611DAB, 0x0B6662D3D, 
            0x76DC4190, 0x1DB7106, 0x98D220BC, 0x0EFD5102A, 0x71B18589, 0x6B6B51F, 0x9FBFE4A5, 0x0E8B8D433, 
            0x7807C9A2, 0x0F00F934, 0x9609A88E, 0x0E10E9818, 0x7F6A0DBB, 0x86D3D2D, 0x91646C97, 0x0E6635C01, 
            0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0x0F262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0x0F50FC457, 
            0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0x0FCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0x0FBD44C65, 
            0x4DB26158, 0x3AB551CE, 0x0A3BC0074, 0x0D4BB30E2, 0x4ADFA541, 0x3DD895D7, 0x0A4D1C46D, 0x0D3D6F4FB, 
            0x4369E96A, 0x346ED9FC, 0x0AD678846, 0x0DA60B8D0, 0x44042D73, 0x33031DE5, 0x0AA0A4C5F, 0x0DD0D7CC9, 
            0x5005713C, 0x270241AA, 0x0BE0B1010, 0x0C90C2086, 0x5768B525, 0x206F85B3, 0x0B966D409, 0x0CE61E49F, 
            0x5EDEF90E, 0x29D9C998, 0x0B0D09822, 0x0C7D7A8B4, 0x59B33D17, 0x2EB40D81, 0x0B7BD5C3B, 0x0C0BA6CAD, 
            0x0EDB88320, 0x9ABFB3B6, 0x3B6E20C, 0x74B1D29A, 0x0EAD54739, 0x9DD277AF, 0x4DB2615, 0x73DC1683, 
            0x0E3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0x0E40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 
            0x0F00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0x0F762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 
            0x0FED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0x0F9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 
            0x0D6D6A3E8, 0x0A1D1937E, 0x38D8C2C4, 0x4FDFF252, 0x0D1BB67F1, 0x0A6BC5767, 0x3FB506DD, 0x48B2364B, 
            0x0D80D2BDA, 0x0AF0A1B4C, 0x36034AF6, 0x41047A60, 0x0DF60EFC3, 0x0A867DF55, 0x316E8EEF, 0x4669BE79, 
            0x0CB61B38C, 0x0BC66831A, 0x256FD2A0, 0x5268E236, 0x0CC0C7795, 0x0BB0B4703, 0x220216B9, 0x5505262F, 
            0x0C5BA3BBE, 0x0B2BD0B28, 0x2BB45A92, 0x5CB36A04, 0x0C2D7FFA7, 0x0B5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 
            0x9B64C2B0, 0x0EC63F226, 0x756AA39C, 0x26D930A, 0x9C0906A9, 0x0EB0E363F, 0x72076785, 0x5005713, 
            0x95BF4A82, 0x0E2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0x0E5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 
            0x86D3D2D4, 0x0F1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0x0F6B9265B, 0x6FB077E1, 0x18B74777, 
            0x88085AE6, 0x0FF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0x0F862AE69, 0x616BFFD3, 0x166CCF45, 
            0x0A00AE278, 0x0D70DD2EE, 0x4E048354, 0x3903B3C2, 0x0A7672661, 0x0D06016F7, 0x4969474D, 0x3E6E77DB, 
            0x0AED16A4A, 0x0D9D65ADC, 0x40DF0B66, 0x37D83BF0, 0x0A9BCAE53, 0x0DEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 
            0x0BDBDF21C, 0x0CABAC28A, 0x53B39330, 0x24B4A3A6, 0x0BAD03605, 0x0CDD70693, 0x54DE5729, 0x23D967BF, 
            0x0B3667A2E, 0x0C4614AB8, 0x5D681B02, 0x2A6F2B94, 0x0B40BBE37, 0x0C30C8EA1, 0x5A05DF1B, 0x2D02EF8D 
        };

        public static UInt32 CrcAccumulate(byte[] inputBuffer, uint currentChecksum = 0, int length = 0) 
        {
            length = length == 0 ? inputBuffer.Length : length;
            for (int i = 0; i < length; i++) 
            {
                uint tableIndex = (currentChecksum ^ inputBuffer[i]) & 0xFF;
                uint tableValue = CrcTable[tableIndex];
                // mix in the loaded byte into the crc on the most significant byte
                currentChecksum >>= 8;
                currentChecksum &= 0xFFFFFF;
                currentChecksum ^= tableValue;
            }

            return currentChecksum;
        }

        public static uint ComputeFileChecksum(byte[] fileBytes)
        {
            // caesar uses a 0x8000 block size
            // const int blockSize = 0x8000;
            const int blockSize = int.MaxValue;

            // skip the appended checksum
            fileBytes = fileBytes.Take(fileBytes.Length - 4).ToArray();

            int fileCursor = 0;
            uint currentChecksum = 0xFFFFFFFF;
            while (fileCursor < fileBytes.Length)
            {
                byte[] blockToRead = fileBytes.Skip(fileCursor).Take(blockSize).ToArray();
                fileCursor += blockSize;
                currentChecksum = CaesarReader.CrcAccumulate(blockToRead, currentChecksum);
            }
            return currentChecksum;
        }
        public static uint ComputeFileChecksumLazy(byte[] fileBytes)
        {
            return CaesarReader.CrcAccumulate(fileBytes, 0xFFFFFFFF, fileBytes.Length - 4);
        }
    }
}


================================================
FILE: Caesar/Caesar/CaesarStructure.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Caesar
{
    class CaesarStructure
    {
        // offsets
        public enum StructureName
        {
            CBFHEADER = 0,
            UNK1 = 1,
            UNK2 = 2,
            UNK3 = 3,
            UNK4 = 4,
            PRESENTATION_STRUCTURE = 0x5,
            UNK6 = 6,
            UNK7 = 7,
            UNK8 = 8,
            UNK9 = 9,
            UNK10 = 0xA,
            SCALEINTERVAL_STRUCTURE = 0xB,
            UNK12 = 0xC,
            UNK13 = 0xD,
            UNK14 = 0xE,
            UNK15 = 0xF,
            FLASH_DESCRIPTION_HEADER = 0x10,
            FLASH_TABLE_STRUCTURE = 0x11,
            UNK18 = 0x12,
            UNK19 = 0x13,
            SESSION_TABLE_STRUCTURE = 0x14,
            UNK21 = 0x15,
            DATA_BLOCK_TABLE_STRUCTURE = 0x16,
            UNK23 = 0x17,
            UNK24 = 0x18,
            UNK25 = 0x19,
            UNK26 = 0x1A,
            SEGMENT_TABLE_STRUCTURE = 0x1B,
            UNK28 = 0x1C,
            CTFHEADER = 0x1D,
            LANGUAGE_TABLE = 0x1E,
            CCFHEADER = 0x1F,
            UNK32 = 0x20,
            CCFFRAGMENT = 0x21,
            UNK34 = 0x22,
            UNK35 = 0x23,
            UNK36 = 0x24,
        }

        /*
        raw values from ida:
        [
	        [2,4,4,4,4,4,4,4,4,4,4,4,4],
	        [4,4,4,2,2,4,4,4,4,4,2,2,2,4,4,4,4,4,4,4,4,4,4,1,1,2,1],
	        [6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2],
	        [6,4,4,2,4,4,4,4,4,4,4,4,4,2,4,4,4,4,4,4,2,2,4,4,2,1,4,4,4,4,4,4],
	        [4,4,4,4,4,4,4,2,2,2,2,1,1,1,1,1,5,1,1,1,1,4,4,4,4,4],
	        [6,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,4,4,4,2,4,4,4],
	        [2,4,4,2,4,4,4,4,4,4,4,4,4],
	        [2,4,4,4,4,2,4,2,4],
	        [2,4,4,4,4,4,4,4,4,4,4,2],
	        [2,4,4,4,4,4,4,4,4],
	        [2,4,4,4],
	        [2,4,4,4,4,4,4,4,4,4,4,4],
	        [2,4,4,4,1,1],
	        [2,4,2,2,2,4,2,2,4,4,4],
	        [2,4,4,4,4,4,4,4,4,1,1],
	        [6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1],
	        [4,4,4,4,4,4,4,4,4,4,4,4,4],
	        [2,4,4,4,4,4,4,4,4,4,4,4,4,4],
	        [2,4,4,4,4,4,4,4,4,4,4,4,4,4],
	        [2,4,4,4,4],
	        [2,4,4,4,4,4,4,4,4,4,2],
	        [2,4,4,4,4,4],
	        [6,4,4,4,4,4,4,4,4,4,4,4,2,4,4,4,4,4,4,4,4,4,4,4,4,4],
	        [2,4,4,4,4],
	        [2,4,4,4,4,4,4],
	        [2,4,4],
	        [2,2,4,4,2,4,4,2,4,4,2,4,4],
	        [2,4,4,4,4,4,4,4],
	        [2,4,4],
	        [2,4,4,2,4,4,4,4,4],
	        [2,4,2,4,4,4],
	        [6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2],
	        [6,4,4,4,4,4,4,4,4,4,4,4,4],
	        [2,4,4,4,4,4,2,4],
	        [2,4,4,4,4,4,2,4],
	        [2,4,4,4,4,4,4,2,4],
	        [2,2,2,2,2,2,2,2,4,4,0,0,0]
        ]
         */
        public static List<byte[]> CaesarTypes = new List<byte[]>();

        public static void GetOffset(StructureName name, int memberIndex) 
        {
            FillCaesarTypes();
        }

        public static byte[] GetCaesarLayout(StructureName name) 
        {
            FillCaesarTypes();
            return CaesarTypes[(int)name];
        }

        public static void FillCaesarTypes() 
        {
            if (CaesarTypes.Count != 0) 
            {
                return;
            }
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // CBFHEADER
            CaesarTypes.Add(new byte[] { 4, 4, 4, 2, 2, 4, 4, 4, 4, 4, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 2, 1 }); // UNK1
            CaesarTypes.Add(new byte[] { 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2 }); // UNK2
            CaesarTypes.Add(new byte[] { 6, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 1, 4, 4, 4, 4, 4, 4 }); // UNK3
            CaesarTypes.Add(new byte[] { 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 4, 4, 4, 4, 4 }); // UNK4
            CaesarTypes.Add(new byte[] { 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 4, 4, 4, 2, 4, 4, 4 }); // PRESENTATION_STRUCTURE
            CaesarTypes.Add(new byte[] { 2, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // UNK6
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 2, 4, 2, 4 }); // UNK7
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2 }); // UNK8
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4 }); // UNK9
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4 }); // UNK10
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // SCALEINTERVAL_STRUCTURE
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 1, 1 }); // UNK12
            CaesarTypes.Add(new byte[] { 2, 4, 2, 2, 2, 4, 2, 2, 4, 4, 4 }); // UNK13
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1 }); // UNK14
            CaesarTypes.Add(new byte[] { 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1 }); // 0xF : FlashHeader : FLASH_DESCRIPTION_HEADER

            CaesarTypes.Add(new byte[] { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // 0x10 : FLASH_DESCRIPTION_HEADER
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // 
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // UNK18
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4 }); // UNK19
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2 }); // SESSION_TABLE_STRUCTURE
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4 }); // UNK21
            CaesarTypes.Add(new byte[] { 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // DATA_BLOCK_TABLE_STRUCTURE
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4 }); // UNK23
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4 }); // UNK24
            CaesarTypes.Add(new byte[] { 2, 4, 4 }); // UNK25
            CaesarTypes.Add(new byte[] { 2, 2, 4, 4, 2, 4, 4, 2, 4, 4, 2, 4, 4 }); // UNK26
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4 }); // SEGMENT_TABLE_STRUCTURE
            CaesarTypes.Add(new byte[] { 2, 4, 4 }); // UNK28
            CaesarTypes.Add(new byte[] { 2, 4, 4, 2, 4, 4, 4, 4, 4 }); // CTFHEADER
            CaesarTypes.Add(new byte[] { 2, 4, 2, 4, 4, 4 }); // LANGUAGE_TABLE
            CaesarTypes.Add(new byte[] { 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2 }); // CCFHEADER
            CaesarTypes.Add(new byte[] { 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // UNK32
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 2, 4 }); // CCFFRAGMENT
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 2, 4 }); // UNK34
            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 2, 4 }); // UNK35
            CaesarTypes.Add(new byte[] { 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 0, 0, 0 }); // UNK36
        }

        // this is an artifact from implementing the reverse-engineered code as-is; since Caesar loads all objects in a greedy strategy (for serialization), 
        // use of ReadCBFWithOffset should be discontinued
        public static int ReadCBFWithOffset(int memberIndex, StructureName structureName, byte[] input)
        {
            int byteOffset = CaesarStructure.GetCBFOffset(memberIndex, structureName, input);
            using (BinaryReader reader = new BinaryReader(new MemoryStream(input)))
            {
                byte[] layout = CaesarStructure.GetCaesarLayout(structureName);
                return CaesarReader.ReadIntWithSize(reader, layout[memberIndex], byteOffset);
            }
        }
        public static uint ReadCBFWithOffsetUnsigned(int memberIndex, StructureName structureName, byte[] input)
        {
            int byteOffset = CaesarStructure.GetCBFOffset(memberIndex, structureName, input);
            using (BinaryReader reader = new BinaryReader(new MemoryStream(input)))
            {
                byte[] layout = CaesarStructure.GetCaesarLayout(structureName);
                return CaesarReader.ReadUIntWithSize(reader, layout[memberIndex], byteOffset);
            }
        }

        public static int GetCBFOffset(int memberIndex, StructureName structureName, byte[] cbfInput)
        {
            // test:
            // byte[] cbfInput = new byte[] { 0x03, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x63, 0x54, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x50, 0x52, 0x45, 0x50, 0x5F, 0x55, 0x6E, 0x73, 0x69, 0x67, 0x6E, 0x65, 0x64, 0x5F, 0x31, 0x42, 0x79, 0x74, 0x65, 0x00 };
            // int member_type = 0x1C; 
            // CaesarStructure.StructureName.PRESENTATION_STRUCTURE
            // result =  0x13

            // essentially checks if a bitflag is active, then returns the byte offset to the member

            byte[] structureLayout = GetCaesarLayout(structureName);

            byte bitmask = 1;
            int arrayOffset = structureLayout[0]; // first structure element is always a static offset, to skip past the bitflags
            int cbfOffset = 0;

            for (int i = 1; i < memberIndex; ++i)
            {
                bool bitflagIsEnabled = (bitmask & cbfInput[cbfOffset]) > 0;
                if (bitflagIsEnabled)
                {
                    if (memberIndex != i)
                    {
                        arrayOffset += structureLayout[i];
                    }
                }
                else if ((memberIndex == i) && !bitflagIsEnabled)
                {
                    // found the requested member, but the member is marked as absent in the bitflag, so there is no value
                    arrayOffset = 0;
                }

                // move on to the next bit, and if our bitflag is fully read, move to the next bitflag
                if (bitmask == 0x80)
                {
                    ++cbfOffset;
                    bitmask = 1;
                }
                else
                {
                    bitmask *= 2;
                }
            }
            return arrayOffset;
        }
    }
}


================================================
FILE: Caesar/Caesar/ComParameter.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Caesar
{
    public class ComParameter
    {
        public int ComParamIndex;
        // this takes precedence over SubinterfaceIndex for KW2C3PE
        public int ParentInterfaceIndex;
        public int SubinterfaceIndex;
        public int Unk5;
        public int Unk_CTF;
        public int Phrase;
        private int DumpSize;
        public byte[] Dump;
       
        public int ComParamValue;
        public string ParamName = "";

        private long BaseAddress;
        CTFLanguage Language;

        public void Restore(CTFLanguage language) 
        {
            Language = language;
        }

        public ComParameter() { }

        // looks exactly like the definition in DIOpenDiagService (#T)
        public ComParameter(BinaryReader reader, long baseAddress, List<ECUInterface> parentEcuInterfaceList, CTFLanguage language) 
        {
            BaseAddress = baseAddress;
            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);
            ulong bitflags = reader.ReadUInt16();

            ComParamIndex = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            ParentInterfaceIndex = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            SubinterfaceIndex = CaesarReader.ReadBitflagInt16(ref bitflags, reader, 0);
            Unk5 = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            Unk_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader); // no -1? ctf strings should have -1
            Phrase = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            DumpSize = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Dump = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, DumpSize, baseAddress);
            ComParamValue = 0;
            if (DumpSize == 4) 
            {
                ComParamValue = BitConverter.ToInt32(Dump, 0);
            }


            ECUInterface parentEcuInterface = parentEcuInterfaceList[ParentInterfaceIndex];

            if (ComParamIndex >= parentEcuInterface.ComParameterNames.Count)
            {
                // throw new Exception("Invalid communication parameter : parent interface has no matching key");
                ParamName = "CP_UNKNOWN_MISSING_KEY";
                Console.WriteLine($"Warning: Tried to load a communication parameter without a parent (value: {ComParamValue}), parent: {parentEcuInterface.Qualifier}.");
            }
            else
            {
                ParamName = parentEcuInterface.ComParameterNames[ComParamIndex];
            }
        }

        public void PrintDebug() 
        {
            Console.WriteLine($"ComParam: id {ComParamIndex} ({ParamName}), v {ComParamValue} 0x{ComParamValue:X8} SI_Index:{SubinterfaceIndex} | parentIndex:{ParentInterfaceIndex} 5:{Unk5} DumpSize:{DumpSize} D: {BitUtility.BytesToHex(Dump)}");
            Console.WriteLine($"Pos 0x{BaseAddress:X}");
        }
    }
}


================================================
FILE: Caesar/Caesar/DSCContext.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace Caesar
{
    public class DSCContext
    {
        public DSCContext(byte[] dscContainerBytes) 
        {
            const int fnTableEntrySize = 50;
            using (BinaryReader reader = new BinaryReader(new MemoryStream(dscContainerBytes, 0, dscContainerBytes.Length, true, true)))
            {
                reader.BaseStream.Seek(0x10, SeekOrigin.Begin);
                int fnTableOffset = reader.ReadInt32(); // @ 0x10, originally i16
                int numberOfFunctions = reader.ReadInt16(); // @ 0x14
                int dscOffsetA = reader.ReadInt32(); // @ 0x16, originally i16
                int caesarHash = reader.ReadInt16(); // @ 0x1A, size is u32?

                int idk_field_1c = reader.ReadInt16(); // ?? @ 1C, padding

                int globalVarAllocSize = reader.ReadInt16(); // @ 1E

                int idk_field_20 = reader.ReadInt16(); // ?? @ 20, padding
                int globalVariablesBufferPtr = reader.ReadInt32(); // ?? @ 22
                int globalVariablesCount = reader.ReadInt16(); // ?? @ 26

                int globalVariablesIdk1 = reader.ReadInt32(); // ?? @ 28
                int globalVariablesIdk2 = reader.ReadInt16(); // ?? @ 2C

                int globalVariablesPreinitBufferPtr = reader.ReadInt32(); // ?? @ 2E
                int globalVariablesBytesToRead = reader.ReadInt16(); // ?? @ 32

                byte[] globalVarByteBuffer = new byte[globalVarAllocSize];

                Console.WriteLine($"{nameof(dscOffsetA)} : {dscOffsetA} (0x{dscOffsetA:X})\n");
                Console.WriteLine($"{nameof(caesarHash)} : {caesarHash} (0x{caesarHash:X})\n");
                Console.WriteLine($"{nameof(globalVarAllocSize)} : {globalVarAllocSize} (0x{globalVarAllocSize:X})\n");

                Console.WriteLine($"{nameof(globalVariablesBufferPtr)} : {globalVariablesBufferPtr} (0x{globalVariablesBufferPtr:X})");
                Console.WriteLine($"{nameof(globalVariablesCount)} : {globalVariablesCount} (0x{globalVariablesCount:X})\n");

                Console.WriteLine($"{nameof(globalVariablesIdk1)} : {globalVariablesIdk1} (0x{globalVariablesIdk1:X})");
                Console.WriteLine($"{nameof(globalVariablesIdk2)} : {globalVariablesIdk2} (0x{globalVariablesIdk2:X})\n");

                Console.WriteLine($"{nameof(globalVariablesPreinitBufferPtr)} : {globalVariablesPreinitBufferPtr} (0x{globalVariablesPreinitBufferPtr:X})");
                Console.WriteLine($"{nameof(globalVariablesBytesToRead)} : {globalVariablesBytesToRead} (0x{globalVariablesBytesToRead:X})\n");

                // assemble global vars: MIGlobalVarBuild (parent: MIInterpreterRun)
                int gvBytesRemaining = globalVariablesBytesToRead;
                reader.BaseStream.Seek(globalVariablesPreinitBufferPtr, SeekOrigin.Begin);
                while (gvBytesRemaining > 0)
                {
                    int gvAddress = reader.ReadInt16();
                    int gvSize = reader.ReadByte();
                    byte[] gvData = reader.ReadBytes(gvSize);
                    Console.WriteLine($"GV Fill: 0x{gvAddress:X} ({gvSize} bytes) : {BitUtility.BytesToHex(gvData)}");
                    Buffer.BlockCopy(gvData, 0, globalVarByteBuffer, gvAddress, gvSize);

                    gvBytesRemaining -= gvSize;
                    gvBytesRemaining -= 3;
                }

                if (gvBytesRemaining != 0) 
                {
                    throw new Exception("Global variable preinit has leftover data in the read cursor");
                }

                // CreateGlobalVar
                for (int gvIndex = 0; gvIndex < globalVariablesCount; gvIndex++)
                {
                    /*
                     guesses:
                    base
                    1 -> char
                    2 -> word
                    3 -> dword


                    derived
                    1 -> native
                    2 -> array
                    3 -> pointer

                     */
                    reader.BaseStream.Seek(globalVariablesBufferPtr + (gvIndex * 12), SeekOrigin.Begin);
                    int varName = reader.ReadInt32();
                    DSCBasicType baseType = (DSCBasicType)reader.ReadInt16();
                    DSCDerivedType derivedType = (DSCDerivedType)reader.ReadInt16();
                    int arraySize = reader.ReadInt16();
                    int positionInGlobalBuffer = reader.ReadInt16();
                    reader.BaseStream.Seek(varName, SeekOrigin.Begin);
                    string varNameResolved = CaesarReader.ReadStringFromBinaryReader(reader, CaesarReader.DefaultEncoding);

                    int dataSizeInBytes = GetDscTypeSize((int)baseType, (int)derivedType);
                    if (derivedType == DSCDerivedType.Array) 
                    {
                        dataSizeInBytes *= arraySize;
                    }
                    byte[] varBytes = new byte[dataSizeInBytes];
                    Buffer.BlockCopy(globalVarByteBuffer, positionInGlobalBuffer, varBytes, 0, dataSizeInBytes);

                    Console.WriteLine($"\nVar: {baseType}/{derivedType} [{arraySize}] @ {positionInGlobalBuffer} : {varNameResolved}");
                    Console.WriteLine($"{BitUtility.BytesToHex(varBytes)}");
                    // actual insertion into global var list is in MIGlobalVarCallback, stored in interpreter's ->GlobalVarList
                }

                for (int fnIndex = 0; fnIndex < numberOfFunctions; fnIndex++)
                {
                    long fnBaseAddress = fnTableEntrySize * fnIndex + fnTableOffset;
                    reader.BaseStream.Seek(fnBaseAddress, SeekOrigin.Begin);

                    int fnIdentifier = reader.ReadInt16(); // @ 0
                    int fnNameOffset = reader.ReadInt32(); // @ 2

                    // not exactly sure if int32 is right -- the first fn's ep looks incorrect in both cases. 
                    // 16 bit would limit the filesize to ~32KB which seems unlikely

                    int fnEntryPoint = reader.ReadInt32(); // @ 6
                    //int fnEntryPoint = reader.ReadInt16(); // @ 6
                    //int fnIdkIsThisStandalone = reader.ReadInt16(); // @ 6

                    reader.BaseStream.Seek(fnBaseAddress + 38, SeekOrigin.Begin);
                    int inputParamOffset = reader.ReadInt32(); // @ 38
                    int inputParamCount = reader.ReadInt16(); // @ 42

                    int outputParamOffset = reader.ReadInt32(); // @ 44
                    int outputParamCount = reader.ReadInt16(); // @ 48

                    reader.BaseStream.Seek(fnNameOffset, SeekOrigin.Begin);
                    string fnName = CaesarReader.ReadStringFromBinaryReader(reader);

                    Console.WriteLine($"Fn: {fnName} Ordinal: {fnIdentifier} EP: 0x{fnEntryPoint:X}, InParam: {inputParamCount} @ 0x{inputParamOffset:X}, OutParam: {outputParamCount} @ 0x{outputParamOffset}");

                    // the EP points to an int16 to initialize the stack height
                    // after the EP, the raw bytecode can be directly interpreted
                }
            }
        }

        public enum DSCBasicType 
        {
            Undefined,
            Char,
            Word,
            DWord,
            Unk_1Byte,
            Unk_2Byte,
            Unk_4Byte,
            Unk_4Byte_2,
        }

        public enum DSCDerivedType 
        {
            Undefined,
            Primitive,
            Array,
            Pointer, // DWORD PTR
        }

        public static int GetDscTypeSize(int basicType, int derivedType)
        {
            // MISizeofVarDataType
            int[] typeSizes = new int[] { -1, 1, 2, 4, 1, 2, 4, 4 };
            // char, word, dword, ??, ??, ??, ??

            if (derivedType == 3)
            {
                return 4; // DWORD PTR
            }
            else if (derivedType < 3)
            {
                if ((basicType > 0) && (basicType < 8))
                {
                    return typeSizes[basicType];
                }
                else
                {
                    throw new Exception("Unrecognized DSC Type: basic type is out of bounds");
                }
            }
            else
            {
                throw new Exception("Unrecognized DSC Type: derived type is out of bounds");
            }
        }
    }
}


================================================
FILE: Caesar/Caesar/DTC.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Caesar
{
    public class DTC
    {
        public enum DTCStatusByte : uint
        {
            TestFailedAtRequestTime = 0x01,
            TestFailedAtCurrentCycle = 0x02,
            PendingDTC = 0x04,
            ConfirmedDTC = 0x08,
            TestIncompleteSinceLastClear = 0x10,
            TestFailedSinceLastClear = 0x20,
            TestIncompleteAtCurrentCycle = 0x40,
            WarningIndicatorActive = 0x80,
        }

        // see : const char *__cdecl DIGetComfortErrorCode(DI_ECUINFO *ecuh, unsigned int dtcIndex)
        public string Qualifier;

        public int Description_CTF;
        public int Reference_CTF;

        public int XrefStart = -1;
        public int XrefCount = -1;

        private long BaseAddress;
        public int PoolIndex;

        [Newtonsoft.Json.JsonIgnore]
        public ECU ParentECU;
        [Newtonsoft.Json.JsonIgnore]
        CTFLanguage Language;

        [Newtonsoft.Json.JsonIgnore]
        public string Description { get { return Language.GetString(Description_CTF); } }

        public void Restore(CTFLanguage language, ECU parentEcu) 
        {
            ParentECU = parentEcu;
            Language = language;
        }

        public DTC() { }

        public DTC(BinaryReader reader, CTFLanguage language, long baseAddress, int poolIndex, ECU parentEcu)
        {
            ParentECU = parentEcu;
            PoolIndex = poolIndex;
            BaseAddress = baseAddress;
            Language = language;
            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);

            ulong bitflags = reader.ReadUInt16();

            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);

            Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            Reference_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
#if DEBUG
            if (bitflags > 0) 
            {
                Console.WriteLine($"DTC {Qualifier} has additional unparsed fields : 0x{bitflags:X}");
            }
#endif
        }
        /*
        public string GetDescription() 
        {
            return Language.GetString(Description_CTF);
        }
        */
        public static DTC FindDTCById(string id, ECUVariant variant)
        {
            foreach (DTC dtc in variant.DTCs)
            {
                if (dtc.Qualifier.EndsWith(id))
                {
                    return dtc;
                }
            }
            return null;
        }
        public void PrintDebug() 
        {
            Console.WriteLine($"DTC: {Qualifier}: {Language.GetString(Description_CTF)} : {Language.GetString(Reference_CTF)}");
        }
    }
}


================================================
FILE: Caesar/Caesar/DiagPreparation.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Caesar
{
    public class DiagPreparation
    {
        public string Qualifier;
        public int Name_CTF;
        public int Unk1;
        public int Unk2;
        public int AlternativeBitWidth;
        public int IITOffset;
        public int InfoPoolIndex;
        public int PresPoolIndex;
        public int Field1E;
        public int SystemParam;
        public int DumpMode;
        private int DumpSize;
        public byte[] Dump;

        public int BitPosition;
        public ushort ModeConfig;
        public int SizeInBits = 0;

        private CTFLanguage Language;

        public static readonly byte[] IntegerSizeMapping = new byte[] { 0x00, 0x01, 0x04, 0x08, 0x10, 0x20, 0x40 };

        long BaseAddress;
        [Newtonsoft.Json.JsonIgnore]
        public ECU ParentECU;
        private DiagService ParentDiagService;

        public InferredDataType FieldType;

        public enum InferredDataType 
        {
            UnassignedType,
            IntegerType,
            NativeInfoPoolType,
            NativePresentationType,
            UnhandledITType,
            UnhandledSP17Type,
            UnhandledType,
            BitDumpType,
            ExtendedBitDumpType,
        }

        public void Restore(CTFLanguage language, ECU parentEcu, DiagService parentDiagService) 
        {
            Language = language;
            ParentECU = parentEcu;
            ParentDiagService = parentDiagService;
        }

        public DiagPreparation() { }

        // void __cdecl DiagServiceReadPresentation(int *inBase, DECODED_PRESENTATION *outPresentation)
        // Looks like its actually a presentation
        // See DIDiagservice* functions
        public DiagPreparation(BinaryReader reader, CTFLanguage language, long baseAddress, int bitPosition, ushort modeConfig, ECU parentEcu, DiagService parentDiagService)
        {
            BitPosition = bitPosition;
            ModeConfig = modeConfig;
            Language = language;
            BaseAddress = baseAddress;
            ParentECU = parentEcu;
            ParentDiagService = parentDiagService;

            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);
            ulong bitflags = reader.ReadUInt32();


            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);
            Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            Unk1 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);
            Unk2 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);
            AlternativeBitWidth = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            IITOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            InfoPoolIndex = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            PresPoolIndex = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Field1E = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            SystemParam = CaesarReader.ReadBitflagInt16(ref bitflags, reader, -1);
            DumpMode = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            DumpSize = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            if (DumpMode == 5) 
            {
                // dump is actually a string, use
                // CaesarReader.ReadBitflagDumpWithReaderAsString
            }
            Dump = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, DumpSize, baseAddress);

            SizeInBits = GetSizeInBits(reader);
            // PrintDebug();
        }

        // look at.. DIInternalRetrieveConstParamPreparation
        // 
        public int GetSizeInBits(BinaryReader reader, bool verbose = true) 
        {
            // if (modeConfig & 0xF00) == 0x300, the value is a const param: DIIsConstParameter

            // VCFragment does the same thing.. with the same ITT exception
            // BitPosition /= 8

            // look for the string "nImplType <= 6"
            uint modeE = (uint)ModeConfig & 0xF000;
            uint modeH = (uint)ModeConfig & 0xFF0;
            uint modeL = (uint)ModeConfig & 0xF;
            int resultBitSize = 0;


            if ((ModeConfig & 0xF00) == 0x300) // this check is made in DIDiagServiceRetrievePreparation
            {
                if (modeL > 6)
                {
                    throw new Exception("nImplType <= 6; trying to map a data type that cannot exist");
                }

                // const params : 0x320, 0x330, 0x340
                if (modeH == 0x320)
                {
                    // this behavior is confirmed
                    resultBitSize = IntegerSizeMapping[modeL];
                    FieldType = InferredDataType.IntegerType;
                }
                else if (modeH == 0x330)
                {
                    // this behavior is also okay
                    resultBitSize = AlternativeBitWidth; // inPres + 20
                    FieldType = InferredDataType.BitDumpType;
                }
                else if (modeH == 0x340)
                {
                    // from dasm, but unimplemented
                    // DIInternalRetrieveConstParamPreparation
                    FieldType = InferredDataType.UnhandledITType;
                    throw new NotImplementedException("WARNING: valid but unhandled data size (ITT not parsed)");
                    // resultBitSize = 0; // inPres + 20
                }
            }
            else 
            {
                // if systemparam is -1.. load a default system type
                if (SystemParam == -1)
                {
                    // apparently both 0x2000 and 0x8000 source from different pools, but use the same PRESENTATION structure
                    if (modeE == 0x8000)
                    {
                        FieldType = InferredDataType.NativeInfoPoolType;
                        byte[] poolBytes = ParentECU.ReadECUInfoPool(reader);
                        using (BinaryReader poolReader = new BinaryReader(new MemoryStream(poolBytes)))
                        {
                            DiagPresentation pres = ParentECU.GlobalInternalPresentations[InfoPoolIndex];
                            /*
                            // depreciate use of ReadCBFWithOffset
                            poolReader.BaseStream.Seek(ParentECU.Info_EntrySize * InfoPoolIndex, SeekOrigin.Begin);

                            int presentationStructOffset = poolReader.ReadInt32();
                            int presentationStructSize = poolReader.ReadInt32();

                            reader.BaseStream.Seek(presentationStructOffset + ParentECU.Info_BlockOffset, SeekOrigin.Begin);
                            byte[] presentationStruct = reader.ReadBytes(presentationStructSize);

                            int presentationMode = CaesarStructure.ReadCBFWithOffset(0x1C, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // PRESS_Type
                            int presentationLength = CaesarStructure.ReadCBFWithOffset(0x1A, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // PRESS_TypeLength
                            if (presentationLength > 0)
                            {
                                resultBitSize = presentationLength;
                            }
                            else
                            {
                                resultBitSize = CaesarStructure.ReadCBFWithOffset(0x21, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // ???
                            }
                            */
                            resultBitSize = pres.TypeLength_1A > 0 ? pres.TypeLength_1A : pres.TypeLengthBytesMaybe_21;

                            // if value was specified in bytes, convert to bits
                            if (pres.Type_1C == 0)
                            {
                                resultBitSize *= 8;
                            }
                        }
                    }
                    else if (modeE == 0x2000)
                    {
                        FieldType = InferredDataType.NativePresentationType;
                        byte[] presPool = ParentECU.ReadECUPresentationsPool(reader);

                        using (BinaryReader poolReader = new BinaryReader(new MemoryStream(presPool)))
                        {
                            DiagPresentation pres = ParentECU.GlobalPresentations[PresPoolIndex];
                            /*
                            // depreciate use of ReadCBFWithOffset
                            poolReader.BaseStream.Seek(ParentECU.Presentations_EntrySize * PresPoolIndex, SeekOrigin.Begin);
                            int presentationStructOffset = poolReader.ReadInt32();
                            int presentationStructSize = poolReader.ReadInt32();

                            reader.BaseStream.Seek(presentationStructOffset + ParentECU.Presentations_BlockOffset, SeekOrigin.Begin);
                            byte[] presentationStruct = reader.ReadBytes(presentationStructSize);
                            
                            int presentationMode = CaesarStructure.ReadCBFWithOffset(0x1C, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // PRESS_Type
                            int presentationLength = CaesarStructure.ReadCBFWithOffset(0x1A, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // PRESS_TypeLength
                            
                            if (presentationLength > 0)
                            {
                                resultBitSize = presentationLength;
                            }
                            else
                            {
                                resultBitSize = CaesarStructure.ReadCBFWithOffset(0x21, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // ???
                            }
                            */

                            resultBitSize = pres.TypeLength_1A > 0 ? pres.TypeLength_1A : pres.TypeLengthBytesMaybe_21;

                            // if value was specified in bytes, convert to bits
                            if (pres.Type_1C == 0)
                            {
                                resultBitSize *= 8;
                            }
                        }
                    }
                    else 
                    {
                        // should throw an exception?
                        //Console.WriteLine($"WARNING: Unknown or unhandled type for for {qualifier}");
                        throw new Exception($"Attempted to load an unknown system type for {Qualifier}");
                    }
                }
                else 
                {
                    // not a const param, not a native param, this is a special param, parsed at DIInternalRetrieveSpecialPreparation
                    // DIInternalRetrieveSpecialPreparation officially supports 0x410, 0x420 only
                    if (modeH == 0x410)
                    {
                        int reducedSysParam = SystemParam - 0x10;
                        if (reducedSysParam == 0)
                        {
                            // specifically requests for LOBYTE (& 0xFF)
                            int resultByteSize = (ParentDiagService.RequestBytes.Length & 0xFF) - (BitPosition / 8);
                            resultBitSize = resultByteSize * 8;
                            FieldType = InferredDataType.ExtendedBitDumpType;
                            // Console.WriteLine($"0x{modeH:X} debug for {qualifier} (L: {modeL}) (BitWidth: {AlternativeBitWidth} SP: {SystemParam}), sz: {resultBitSize} b ({resultBitSize/8} B)");
                        }
                        else if (reducedSysParam == 17)
                        {
                            // open a diagservice based on inputRef name
                            // this is experimental, haven't seen a cbf that uses this yet
                            Console.WriteLine($"Parsing experimental 0x410 prep with sysparam 17 at {Qualifier}");
                            DiagService referencedDs = ParentECU.GlobalDiagServices.Find(x => x.Qualifier == ParentDiagService.InputRefNameMaybe);
                            if (referencedDs != null)
                            {
                                bool referencedDsHasRequestData = referencedDs.RequestBytes.Length > 0; // supposed to check if requestMessage is valid too
                                int internalType = referencedDs.DataClass_ServiceTypeShifted;
                                if (((referencedDs.DataClass_ServiceTypeShifted & 0xC) > 0) && referencedDsHasRequestData)
                                {
                                    if ((referencedDs.DataClass_ServiceTypeShifted & 4) > 0)
                                    {
                                        internalType = 0x10000000;
                                    }
                                    else
                                    {
                                        internalType = 0x20000000;
                                    }
                                }
                                if ((internalType & 0x10000) != 0)
                                {
                                    // referenced type is a global variable
                                    resultBitSize = ParentDiagService.P_Count * 8;
                                    FieldType = InferredDataType.UnhandledSP17Type;
                                }
                                else
                                {
                                    // use pres dump length
                                    FieldType = InferredDataType.UnhandledSP17Type;
                                    resultBitSize = ParentDiagService.RequestBytes.Length * 8;
                                }
                            }
                            else
                            {
                                Console.WriteLine($"0x410 : sys param: 17 for qualifier {Qualifier} could not find referenced DiagService with index {ParentDiagService.InputRefNameMaybe}");
                                // throw new NotImplementedException
                            }
                        }
                        else
                        {
                            throw new Exception($"Invalid system parameter for {Qualifier}");
                        }
                    }
                    else if (modeH == 0x420)
                    {
                        if (modeL > 6)
                        {
                            throw new Exception("nImplType <= 6; trying to map a data type that cannot exist");
                        }
                        FieldType = InferredDataType.IntegerType;
                        resultBitSize = IntegerSizeMapping[modeL];
                    }
                    else if (modeH == 0x430)
                    {
                        // mode 0x430 is nonstandard and doesn't seem to exist in the function that I was disassembling
                        /*
                            AlternativeBitWidth : 128
                            SystemParam : 37
                            
                            See 0x320 vs 0x330, seems to be similar
                        */

                        resultBitSize = AlternativeBitWidth; // inPres + 20
                        FieldType = InferredDataType.BitDumpType;
                    }
                    else
                    {
                        FieldType = InferredDataType.UnhandledType;
                        Console.WriteLine($"Unhandled type: {modeH} for {Qualifier}");
                        PrintDebug();
                        throw new Exception($"Attempted to load an unknown special param type for {Qualifier}");
                        //Console.WriteLine($"{qualifier} ({poolThing}/{ParentECU.ecuInfoPool_tableEntryCount})\n{BitUtility.BytesToHex(presentationStruct)}\n\n");
                    }
                }
            }


            /*
            if (modeH == 0x430)
            {
                // guessed
                if (verbose)
                {
                    Console.WriteLine($"Unsupported 0x{modeH:X} behavior for {qualifier} (L: {modeL}) (BitWidth: {AlternativeBitWidth} ByteWidth: {SystemParam})");
                }
                //PrintDebug();
                resultBitSize = AlternativeBitWidth; // alternate bit width is 128 which should be a nice 16 bytes
            }
            else if (modeH > 0x430)
            {
                // guessed from varcoding behavior
                if ((PresPool == 0) && (AvailableBitWidth_PoolThing == 0))
                {
                    return 0;
                }
                else
                {
                    //Console.WriteLine($"No idea how to handle Pres 0x750 from {qualifier} : {PresPool}");
                }
                Console.WriteLine($"No idea how to handle 0x{modeH:X} from {qualifier} ({PresPool}, {AvailableBitWidth_PoolThing})");
            }
            */
            return resultBitSize;
        }

        public void PrintDebug()
        {
            Console.WriteLine($"{nameof(Qualifier)} : {Qualifier}");
            Console.WriteLine($"{nameof(BitPosition)} : {BitPosition}");
            Console.WriteLine($"{nameof(ModeConfig)} : 0x{ModeConfig:X}");
            Console.WriteLine($"Mode H : 0x{ModeConfig & 0xFF0:X}, L : 0x{ModeConfig & 0xF:X}");
            Console.WriteLine($"{nameof(SizeInBits)} : 0x{SizeInBits:X}");
            Console.WriteLine($"{nameof(Name_CTF)} : {Name_CTF}");
            Console.WriteLine($"{nameof(Name_CTF)} : {Language.GetString(Name_CTF)}");
            Console.WriteLine($"{nameof(Unk1)} : {Unk1}");
            Console.WriteLine($"{nameof(Unk2)} : {Unk2}");
            Console.WriteLine($"{nameof(AlternativeBitWidth)} : {AlternativeBitWidth}");
            Console.WriteLine($"{nameof(IITOffset)} : {IITOffset}");
            Console.WriteLine($"{nameof(InfoPoolIndex)} : {InfoPoolIndex}");
            Console.WriteLine($"{nameof(PresPoolIndex)} : {PresPoolIndex}");
            Console.WriteLine($"{nameof(Field1E)} : {Field1E}");
            Console.WriteLine($"{nameof(SystemParam)} : {SystemParam}");
            // Console.WriteLine($"{nameof(noIdea_T)} : {language.GetString(noIdea_T)}");
            Console.WriteLine($"{nameof(Dump)} : {BitUtility.BytesToHex(Dump)}");
            Console.WriteLine("---------------");
        }
    }
}


================================================
FILE: Caesar/Caesar/DiagPresentation.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Caesar
{
    public class DiagPresentation
    {
        public string Qualifier;
        public int Description_CTF;
        public int ScaleTableOffset;
        public int ScaleCountMaybe;
        public int Unk5;
        public int Unk6;
        public int Unk7;
        public int Unk8;
        public int Unk9;
        public int UnkA;
        public int UnkB;
        public int UnkC;
        public int UnkD;
        public int UnkE;
        public int UnkF;
        public int DisplayedUnit_CTF;
        public int Unk11;
        public int Unk12;
        public int EnumMaxValue;
        public int Unk14;
        public int Unk15;
        public int Description2_CTF;
        public int Unk17;
        public int Unk18;
        public int Unk19;
        public int TypeLength_1A;
        public int InternalDataType; // discovered by @prj : #37
        public int Type_1C;
        public int Unk1d;
        public int SignBit; // discovered by @prj : #37
        public int ByteOrder; // discovered by @prj : #37 ; Unset = HiLo, 1 = LoHi
        public int Unk20;

        public int TypeLengthBytesMaybe_21;
        public int Unk22;
        public int Unk23;
        public int Unk24;
        public int Unk25;
        public int Unk26;
        // public string DescriptionString;
        // public string DisplayedUnitString;
        // public string DescriptionString2;

        private long BaseAddress;
        public int PresentationIndex;



        [Newtonsoft.Json.JsonIgnore]
        public string DescriptionString { get { return Language.GetString(Description_CTF); } }
        [Newtonsoft.Json.JsonIgnore]
        public string DisplayedUnitString { get { return Language.GetString(DisplayedUnit_CTF); } }
        [Newtonsoft.Json.JsonIgnore]
        public string DescriptionString2 { get { return Language.GetString(Description2_CTF); } }

        [Newtonsoft.Json.JsonIgnore]
        public CTFLanguage Language;

        public List<Scale> Scales = new List<Scale>();

        public void Restore(CTFLanguage language) 
        {
            Language = language;
            foreach (Scale s in Scales) 
            {
                s.Restore(language);
            }
        }

        public DiagPresentation() { }

        // 0x05 [6,   4,4,4,4,  4,4,4,4,  4,4,4,4,  2,2,2,4,      4,4,4,4,   4,4,4,4,   4,4,1,1,  1,1,1,4,     4,4,2,4,   4,4],

        public DiagPresentation(BinaryReader reader, long baseAddress, int presentationsIndex, CTFLanguage language) 
        {
            BaseAddress = baseAddress;
            PresentationIndex = presentationsIndex;
            Language = language;

            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);
            ulong bitflags = reader.ReadUInt32();
            
            ulong extendedBitflags = reader.ReadUInt16(); // skip 2 bytes

            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress);

            Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            ScaleTableOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            ScaleCountMaybe = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Unk5 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            Unk6 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Unk7 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Unk8 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Unk9 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            UnkA = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            UnkB = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            UnkC = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            UnkD = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            UnkE = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            UnkF = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            DisplayedUnit_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);

            Unk11 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Unk12 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            EnumMaxValue = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Unk14 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);

            Unk15 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Description2_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            Unk17 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            Unk18 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Unk19 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            TypeLength_1A = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            InternalDataType = CaesarReader.ReadBitflagInt8(ref bitflags, reader, -1);
            Type_1C = CaesarReader.ReadBitflagInt8(ref bitflags, reader, -1);

            Unk1d = CaesarReader.ReadBitflagInt8(ref bitflags, reader);
            SignBit = CaesarReader.ReadBitflagInt8(ref bitflags, reader);
            ByteOrder = CaesarReader.ReadBitflagInt8(ref bitflags, reader);
            Unk20 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            bitflags = extendedBitflags;

            TypeLengthBytesMaybe_21 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Unk22 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            Unk23 = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            Unk24 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Unk25 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Unk26 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);


            long scaleTableBase = BaseAddress + ScaleTableOffset;
            Scales = new List<Scale>();
            for (int i = 0; i < ScaleCountMaybe; i++) 
            {
                reader.BaseStream.Seek(scaleTableBase + (i * 4), SeekOrigin.Begin);
                int entryRelativeOffset = reader.ReadInt32();

                Scale scale = new Scale(reader, scaleTableBase + entryRelativeOffset, language);
                Scales.Add(scale);
            }
        }

        public string InterpretData(byte[] inBytes, DiagPreparation inPreparation, bool describe = true)
        {
            // might be relevant: DMPrepareSingleDatum, DMPresentSingleDatum

            bool isDebugBuild = false;
#if DEBUG
            isDebugBuild = true;
#endif

            string descriptionPrefix = describe ? $"{DescriptionString}: " : "";
            byte[] workingBytes = inBytes.Skip(inPreparation.BitPosition / 8).Take(TypeLength_1A).ToArray();

            bool isEnumType = (SignBit == 0) && ((Type_1C == 1) || (ScaleCountMaybe > 1));

            // hack: sometimes hybrid types (regularly parsed as an scaled value if within bounds) are misinterpreted as pure enums
            // this is a temporary fix for kilometerstand until there's a better way to ascertain its type
            // this also won't work on other similar cases without a unit string e.g. error instance counter (Häufigkeitszähler)
            if (DisplayedUnitString == "km") 
            {
                isEnumType = false;
            }

            if (workingBytes.Length != TypeLength_1A)
            {
                return $"InBytes [{BitUtility.BytesToHex(workingBytes)}] length mismatch (expecting {TypeLength_1A})";
            }

            // handle booleans first since they're the edge case where they can cross byte boundaries
            if (inPreparation.SizeInBits == 1)
            {
                int bytesToSkip = (int)(inPreparation.BitPosition / 8);
                int bitsToSkip = inPreparation.BitPosition % 8;
                byte selectedByte = inBytes[bytesToSkip];

                int selectedBit = (selectedByte >> bitsToSkip) & 1;
                if (isEnumType && (Scales.Count > selectedBit))
                {
                    return $"{descriptionPrefix}{Language.GetString(Scales[selectedBit].EnumDescription)} {DisplayedUnitString}";
                }
                else 
                {
                    return $"{descriptionPrefix}{selectedBit} {DisplayedUnitString}";
                }
            }

            // everything else should be aligned to byte boundaries
            if (inPreparation.BitPosition % 8 != 0)
            {
                return "BitOffset was outside byte boundary (skipped)";
            }
            int dataType = GetDataType();
            int rawIntInterpretation = 0;

            string humanReadableType = $"UnhandledType:{dataType}";
            string parsedValue = BitUtility.BytesToHex(workingBytes, true);
            if (dataType == 20)
            {
                // parse as a regular int (BE)
                for (int i = 0; i < workingBytes.Length; i++)
                {
                    rawIntInterpretation <<= 8;
                    rawIntInterpretation |= workingBytes[i];
                }

                humanReadableType = "IntegerType";

                parsedValue = rawIntInterpretation.ToString();
                if (dataType == 20)
                {
                    humanReadableType = "ScaledType";

                    double valueToScale = rawIntInterpretation;

                    // if there's only one scale, use it as-is
                    // if there's more than one, use the first scale as an interim solution;
                    // the results of stacking scales does not make sense
                    // there might be a better, non-hardcoded (0) solution to this, and perhaps with a sig-fig specifier

                    valueToScale *= Scales[0].MultiplyFactor;
                    valueToScale += Scales[0].AddConstOffset;

                    parsedValue = valueToScale.ToString("0.000000");
                }
            }
            else if (dataType == 6) 
            {
                // type 6 refers to either internal presentation types 8 (ieee754 float) or 5 (unsigned int?)
                // these values are tagged with an exclamation [!] i (jglim) am not sure if they will work correctly yet
                // specifically, i am not sure if the big endian float parsing is done correctly
                uint rawUIntInterpretation = 0;
                for (int i = 0; i < 4; i++)
                {
                    rawUIntInterpretation <<= 8;
                    rawUIntInterpretation |= workingBytes[i];
                }

                if (InternalDataType == 8)
                {
                    // interpret as big-endian float, https://github.com/jglim/CaesarSuite/issues/37
                    parsedValue = BitUtility.ToFloat(rawUIntInterpretation).ToString("");
                    humanReadableType = "Float [!]";
                }
                else if (InternalDataType == 5) 
                {
                    // haven't seen this one around, will parse as a regular int (BE) for now
                    humanReadableType = "UnsignedIntegerType [!]";
                    parsedValue = rawUIntInterpretation.ToString();
                }
            }
            else if (dataType == 18)
            {
                humanReadableType = "HexdumpType";
            }
            else if (dataType == 17)
            {
                humanReadableType = "StringType";
                parsedValue = Encoding.UTF8.GetString(workingBytes);
            }

            if (isEnumType)
            {
                // discovered by @VladLupashevskyi in https://github.com/jglim/CaesarSuite/issues/27
                // if an enum is specified, the inclusive upper bound and lower bound will be defined in the scale object

                bool useNewInterpretation = false;
                foreach (Scale scale in Scales)
                {
                    if ((scale.EnumUpBound > 0) || (scale.EnumLowBound > 0))
                    {
                        useNewInterpretation = true;
                        break;
                    }
                }

                if (useNewInterpretation)
                {
                    foreach (Scale scale in Scales)
                    {
                        if ((rawIntInterpretation >= scale.EnumLowBound) && (rawIntInterpretation <= scale.EnumUpBound))
                        {
                            return $"{descriptionPrefix}{Language.GetString(scale.EnumDescription)} {DisplayedUnitString}";
                        }
                    }
                }
                else 
                {
                    // original implementation, probably incorrect
                    if (rawIntInterpretation < Scales.Count)
                    {
                        return $"{descriptionPrefix}{Language.GetString(Scales[rawIntInterpretation].EnumDescription)} {DisplayedUnitString}";
                    }
                }
                return $"{descriptionPrefix}(Enum not found) {DisplayedUnitString}";
                // this bit below for troubleshooting problematic presentations
                /*
                if (rawIntInterpretation < Scales.Count)
                {
                    return $"{descriptionPrefix}{Language.GetString(Scales[rawIntInterpretation].EnumDescription)} {DisplayedUnitString}";
                }
                else 
                {
                    // seems like an enum-like value broke
                    return $"{descriptionPrefix}{Language.GetString(Scales[0].EnumDescription)} {DisplayedUnitString} [!]";
                }
                */
            }
            else
            {
                if (isDebugBuild)
                {
                    return $"{descriptionPrefix}{parsedValue} {DisplayedUnitString} ({humanReadableType})";
                }
                else
                {
                    return $"{descriptionPrefix}{parsedValue} {DisplayedUnitString}";
                }
            }
        }

        public int GetDataType() 
        {
            // see DIDiagServiceRealPresType
            int result = -1;
            if (Unk14 != -1) 
            {
                return 20;
            }

            // does the value have scale structures attached to it? 
            // supposed to parse scale struct and check if we can return 20
            if (ScaleTableOffset != -1)
            {
                return 20; // scaled value
            }
            else
            {
                if (Unk5 != -1)
                {
                    return 18; // hexdump raw
                }
                if (Unk17 != -1)
                {
                    return 18; // hexdump raw
                }
                if (Unk19 != -1)
                {
                    return 18; // hexdump raw
                }
                if (Unk22 != -1)
                {
                    return 18; // hexdump raw
                }
                if (InternalDataType != -1)
                {
                    if (InternalDataType == 6)
                    {
                        return 17; // ascii dump
                    }
                    else if (InternalDataType == 7)
                    {
                        return 22; // ?? haven't seen this one around
                    }
                    else if (InternalDataType == 8)
                    {
                        result = 6; // IEEE754 float, discovered by @prj in https://github.com/jglim/CaesarSuite/issues/37
                    }
                    else if (InternalDataType == 5) 
                    {
                        // UNSIGNED integer (i haven't seen a const for uint around, sticking it into a regular int for now)
                        // this will be an issue for 32-bit+ uints
                        // see DT_STO_Zaehler_Programmierversuche_Reprogramming and DT_STO_ID_Aktive_Diagnose_Information_Version
                        result = 6; 
                    }
                }
                else 
                {
                    if ((TypeLength_1A == -1) || (Type_1C == -1)) 
                    {
                        Console.WriteLine("typelength and type must be valid");
                        // might be good to throw an exception here
                    }
                    if ((SignBit == 1) || (SignBit == 2))
                    {
                        result = 5; // ?? haven't seen this one around
                    }
                    else 
                    {
                        result = 2; // ?? haven't seen this one around
                    }
                }
                return result;
            }
        }

        public void PrintDebug()
        {
            Console.WriteLine("Presentation: ");
            Console.WriteLine($"{nameof(Qualifier)}: {Qualifier}");


            //Console.WriteLine($"{nameof(Description_CTF)}: {Description_CTF}");
            Console.WriteLine($"{nameof(ScaleTableOffset)}: {ScaleTableOffset}");
            Console.WriteLine($"{nameof(ScaleCountMaybe)}: {ScaleCountMaybe}");

            Console.WriteLine($"{nameof(Unk5)}: {Unk5}");
            Console.WriteLine($"{nameof(Unk6)}: {Unk6}");
            Console.WriteLine($"{nameof(Unk7)}: {Unk7}");
            Console.WriteLine($"{nameof(Unk8)}: {Unk8}");

            Console.WriteLine($"{nameof(Unk9)}: {Unk9}");
            Console.WriteLine($"{nameof(UnkA)}: {UnkA}");
            Console.WriteLine($"{nameof(UnkB)}: {UnkB}");
            Console.WriteLine($"{nameof(UnkC)}: {UnkC}");

            Console.WriteLine($"{nameof(UnkD)}: {UnkD}");
            Console.WriteLine($"{nameof(UnkE)}: {UnkE}");
            Console.WriteLine($"{nameof(UnkF)}: {UnkF}");
            //Console.WriteLine($"{nameof(DisplayedUnit_CTF)}: {DisplayedUnit_CTF}");

            Console.WriteLine($"{nameof(Unk11)}: {Unk11}");
            Console.WriteLine($"{nameof(Unk12)}: {Unk12}");
            Console.WriteLine($"{nameof(EnumMaxValue)}: {EnumMaxValue}");
            Console.WriteLine($"{nameof(Unk14)}: {Unk14}");

            Console.WriteLine($"{nameof(Unk15)}: {Unk15}");
            // Console.WriteLine($"{nameof(Description2_CTF)}: {Description2_CTF}");
            Console.WriteLine($"{nameof(Unk17)}: {Unk17}");
            Console.WriteLine($"{nameof(Unk18)}: {Unk18}");

            Console.WriteLine($"{nameof(Unk19)}: {Unk19}");
            Console.WriteLine($"{nameof(InternalDataType)}: {InternalDataType}");

            Console.WriteLine($"{nameof(Unk1d)}: {Unk1d}");
            Console.WriteLine($"{nameof(SignBit)}: {SignBit}");
            Console.WriteLine($"{nameof(ByteOrder)}: {ByteOrder}");
            Console.WriteLine($"{nameof(Unk20)}: {Unk20}");

            Console.WriteLine($"{nameof(TypeLengthBytesMaybe_21)}: {TypeLengthBytesMaybe_21}");
            Console.WriteLine($"{nameof(Unk22)}: {Unk22}");
            Console.WriteLine($"{nameof(Unk23)}: {Unk23}");
            Console.WriteLine($"{nameof(Unk24)}: {Unk24}");

            Console.WriteLine($"{nameof(Unk25)}: {Unk25}");
            Console.WriteLine($"{nameof(Unk26)}: {Unk26}");
            /**/


            Console.WriteLine($"{nameof(DescriptionString)}: {DescriptionString}");
            Console.WriteLine($"{nameof(DisplayedUnitString)}: {DisplayedUnitString}");
            Console.WriteLine($"{nameof(DescriptionString2)}: {DescriptionString2}");
            Console.WriteLine($"Type: {GetDataType()}");
            Console.WriteLine($"{nameof(Type_1C)}: {Type_1C}");
            Console.WriteLine($"{nameof(TypeLength_1A)}: {TypeLength_1A}");
            Console.WriteLine($"ScaleOffset: 0x{(ScaleTableOffset + BaseAddress):X}, base of pres @ 0x{BaseAddress:X}");

            foreach (Scale s in Scales)
            {
                Console.WriteLine("Scale: ");
                s.PrintDebug();
            }

            Console.WriteLine("Presentation end");
        }

        public string CopyMinDebug()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("PRES: ");
            sb.Append($" {nameof(Unk5)}: {Unk5}");
            sb.Append($" {nameof(Unk6)}: {Unk6}");
            sb.Append($" {nameof(Unk7)}: {Unk7}");
            sb.Append($" {nameof(Unk8)}: {Unk8}");
            sb.Append($" {nameof(Unk9)}: {Unk9}");
            sb.Append($" {nameof(UnkA)}: {UnkA}");
            sb.Append($" {nameof(UnkB)}: {UnkB}");
            sb.Append($" {nameof(UnkC)}: {UnkC}");
            sb.Append($" {nameof(UnkD)}: {UnkD}");
            sb.Append($" {nameof(UnkE)}: {UnkE}");
            sb.Append($" {nameof(UnkF)}: {UnkF}");
            sb.Append($" {nameof(Unk11)}: {Unk11}");
            sb.Append($" {nameof(Unk12)}: {Unk12}");
            sb.Append($" {nameof(EnumMaxValue)}: {EnumMaxValue}");
            sb.Append($" {nameof(Unk14)}: {Unk14}");
            sb.Append($" {nameof(Unk15)}: {Unk15}");
            sb.Append($" {nameof(Unk17)}: {Unk17}");
            sb.Append($" {nameof(Unk18)}: {Unk18}");
            sb.Append($" {nameof(Unk19)}: {Unk19}");
            sb.Append($" {nameof(InternalDataType)}: {InternalDataType}");
            sb.Append($" {nameof(Unk1d)}: {Unk1d}");
            sb.Append($" {nameof(SignBit)}: {SignBit}");
            sb.Append($" {nameof(ByteOrder)}: {ByteOrder}");
            sb.Append($" {nameof(Unk20)}: {Unk20}");
            sb.Append($" {nameof(TypeLengthBytesMaybe_21)}: {TypeLengthBytesMaybe_21}");
            sb.Append($" {nameof(Unk22)}: {Unk22}");
            sb.Append($" {nameof(Unk23)}: {Unk23}");
            sb.Append($" {nameof(Unk24)}: {Unk24}");
            sb.Append($" {nameof(Unk25)}: {Unk25}");
            sb.Append($" {nameof(Unk26)}: {Unk26}");
            sb.Append($" {nameof(BaseAddress)}: 0x{BaseAddress:X8}");
            sb.Append($" {nameof(Type_1C)}: {Type_1C}");
            sb.Append($" {nameof(TypeLength_1A)}: {TypeLength_1A}");
            sb.Append($" Type: {GetDataType()}");
            sb.Append($" {nameof(ScaleTableOffset)}: {ScaleTableOffset}");
            sb.Append($" {nameof(Qualifier)}: {Qualifier}"); sb.Append($" {nameof(ScaleCountMaybe)}: {ScaleCountMaybe}");
            if (ScaleCountMaybe > 0)
            {
                sb.Append($" {Language.GetString(Scales[0].EnumDescription)}");
            }
            return sb.ToString();
        }


    }
}


================================================
FILE: Caesar/Caesar/DiagService.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Caesar
{

    // DIAGJOB *__cdecl DIOpenDiagService(DI_ECUINFO *ecuHandle, char *serviceName, int ecuErrors)
    public class DiagService
    {
        /*
    5	DT	DATA
    7	DL	DOWNLOAD
    10	FN|DNU	DIAGNOSTIC_U, FN
    19	DJ	DIAGNOSTIC_JOB
    21	SES	SESSION
    22	DT_STO	STORED DATA
    23	RT	ROUTINE
    24	IOC	IO CONTROL
    26	WVC	VARIANTCODING WRITE
    27	WVC	VARIANTCODING READ

         */
        public enum ServiceType
        {
            Data = 5,
            Download = 7,
            DiagnosticFunction = 10,
            DiagnosticJob = 19,
            Session = 21,
            StoredData = 22,
            Routine = 23,
            IoControl = 24,
            VariantCodingWrite = 26,
            VariantCodingRead = 27,
        }

        public string Qualifier;

        public int Name_CTF;
        public int Description_CTF;

        public ushort DataClass_ServiceType;
        public int DataClass_ServiceTypeShifted;

        public ushort IsExecutable;
        public ushort ClientAccessLevel;
        public ushort SecurityAccessLevel;

        private int T_ComParam_Count;
        private int T_ComParam_Offset;

        private int Q_Count;
        private int Q_Offset;

        private int R_Count;
        private int R_Offset;

        public string InputRefNameMaybe;

        private int U_prep_Count;
        private int U_prep_Offset;

        private int V_Count;
        private int V_Offset;

        private int RequestBytes_Count;
        private int RequestBytes_Offset;

        private int W_OutPres_Count;
        private int W_OutPres_Offset;

        public ushort Field50;

        public string NegativeResponseName;
        public string UnkStr3;
        public string UnkStr4;

        public int P_Count; // global vars?
        public int P_Offset;

        private int DiagServiceCodeCount;
        private int DiagServiceCodeOffset;

        private int S_Count;
        private int S_Offset;

        private int X_Count;
        private int X_Offset;

        private int Y_Count;
        private int Y_Offset;

        private int Z_Count;
        private int Z_Offset;

        public byte[] RequestBytes;

        private long BaseAddress;
        public int PoolIndex;

        // these are inlined preparations
        public List<DiagPreparation> InputPreparations = new List<DiagPreparation>();
        public List<List<DiagPreparation>> OutputPreparations = new List<List<DiagPreparation>>();
        public List<ComParameter> DiagComParameters = new List<ComParameter>();

        [Newtonsoft.Json.JsonIgnore]
        public ECU ParentECU;
        private CTFLanguage Language;

        public void Restore(CTFLanguage language, ECU parentEcu) 
        {
            Language = language;
            ParentECU = parentEcu;
            foreach (DiagPreparation dp in InputPreparations)
            {
                dp.Restore(language, parentEcu, this);
            }
            foreach (List<DiagPreparation> dpl in OutputPreparations)
            {
                foreach (DiagPreparation dp in dpl)
                {
                    dp.Restore(language, parentEcu, this);
                }
            }
            /*
            // nothing in comparam to restore
            foreach (ComParameter cp in DiagComParameters) 
            {
            
            }
            */
        }

        public DiagService() { }

        public DiagService(BinaryReader reader, CTFLanguage language, long baseAddress, int poolIndex, ECU parentEcu) 
        {
            ParentECU = parentEcu;
            Language = language;
            PoolIndex = poolIndex;
            BaseAddress = baseAddress;
            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);

            ulong bitflags = reader.ReadUInt32();
            ulong bitflagExtended = reader.ReadUInt32();

            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);

            Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);

            DataClass_ServiceType = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);
            DataClass_ServiceTypeShifted = 1 << (DataClass_ServiceType - 1);

            IsExecutable = CaesarReader.ReadBitflagUInt16(ref bitflags, reader); ;
            ClientAccessLevel = CaesarReader.ReadBitflagUInt16(ref bitflags, reader); ;
            SecurityAccessLevel = CaesarReader.ReadBitflagUInt16(ref bitflags, reader); ;

            T_ComParam_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            T_ComParam_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Q_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Q_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            R_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            R_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            InputRefNameMaybe = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);

            U_prep_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            U_prep_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            // array of DWORDs, probably reference to elsewhere
            V_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            V_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            RequestBytes_Count = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            RequestBytes_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            W_OutPres_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            W_OutPres_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Field50 = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);

            NegativeResponseName = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); // negative response name
            UnkStr3 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);
            UnkStr4 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);

            P_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            P_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            DiagServiceCodeCount = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            DiagServiceCodeOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            S_Count = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            S_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            bitflags = bitflagExtended;
            
            X_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            X_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Y_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Y_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Z_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Z_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            if (RequestBytes_Count > 0)
            {
                reader.BaseStream.Seek(baseAddress + RequestBytes_Offset, SeekOrigin.Begin);
                RequestBytes = reader.ReadBytes(RequestBytes_Count);
            }
            else 
            {
                RequestBytes = new byte[] { };
            }

            // u_table to u_entries
            InputPreparations = new List<DiagPreparation>();
            for (int prepIndex = 0; prepIndex < U_prep_Count; prepIndex++)
            {
                long presentationTableOffset = baseAddress + U_prep_Offset;
                reader.BaseStream.Seek(presentationTableOffset + (prepIndex * 10), SeekOrigin.Begin);

                // DIOpenDiagService (reads 4, 4, 2 then calls DiagServiceReadPresentation) to build a presentation
                int prepEntryOffset = reader.ReadInt32(); // file: 0 (DW)
                int prepEntryBitPos = reader.ReadInt32(); // file: 4 (DW)
                ushort prepEntryMode = reader.ReadUInt16(); // file: 8 (W)

                DiagPreparation preparation = new DiagPreparation(reader, language, presentationTableOffset + prepEntryOffset, prepEntryBitPos, prepEntryMode, parentEcu, this);
                //preparation.PrintDebug();
                InputPreparations.Add(preparation);
            }


            OutputPreparations = new List<List<DiagPreparation>>();
            long outPresBaseAddress = BaseAddress + W_OutPres_Offset;

            // FIXME: run it through the entire dbr cbf directory, check if any file actually has more than 1 item in ResultPresentationSet
            for (int presIndex = 0; presIndex < W_OutPres_Count; presIndex++)
            {
                reader.BaseStream.Seek(outPresBaseAddress + (presIndex * 8), SeekOrigin.Begin);
                // FIXME
                int resultPresentationCount = reader.ReadInt32(); // index? if true, will fix the "wtf" list<list<diagprep>>
                int resultPresentationOffset = reader.ReadInt32();

                List<DiagPreparation> ResultPresentationSet = new List<DiagPreparation>();
                for (int presInnerIndex = 0; presInnerIndex < resultPresentationCount; presInnerIndex++)
                {
                    long presentationTableOffset = outPresBaseAddress + resultPresentationOffset;

                    reader.BaseStream.Seek(presentationTableOffset + (presIndex * 10), SeekOrigin.Begin);

                    int prepEntryOffset = reader.ReadInt32(); // file: 0 (DW)
                    int prepEntryBitPos = reader.ReadInt32(); // file: 4 (DW)
                    ushort prepEntryMode = reader.ReadUInt16(); // file: 8 (W)

                    DiagPreparation preparation = new DiagPreparation(reader, language, presentationTableOffset + prepEntryOffset, prepEntryBitPos, prepEntryMode, parentEcu, this);
                    ResultPresentationSet.Add(preparation);
                }
                OutputPreparations.Add(ResultPresentationSet);
            }

            DiagComParameters = new List<ComParameter>();
            long comParamTableBaseAddress = BaseAddress + T_ComParam_Offset;
            for (int cpIndex = 0; cpIndex < T_ComParam_Count; cpIndex++)
            {
                reader.BaseStream.Seek(comParamTableBaseAddress + (cpIndex * 4), SeekOrigin.Begin);
                int resultCpOffset = reader.ReadInt32();
                long cpEntryBaseAddress = comParamTableBaseAddress + resultCpOffset;
                ComParameter cp = new ComParameter(reader, cpEntryBaseAddress, parentEcu.ECUInterfaces, language);
                DiagComParameters.Add(cp);
            }

            // DJ_Zugriffsberechtigung_Abgleich
            // DJ_Zugriffsberechtigung
            // DT_Abgasklappe_kontinuierlich
            // FN_HardReset
            // WVC_Implizite_Variantenkodierung_Write

            // NR_Disable_Resp_required noexec
            // DT_Laufzeiten_Resetzaehler_nicht_implementiert exec
            /*
            if (false && qualifierName.Contains("RVC_SCN_Variantencodierung_VGS_73_Lesen"))
            {

                Console.WriteLine($"{nameof(field50)} : {field50}");
                Console.WriteLine($"{nameof(IsExecutable)} : {IsExecutable} {IsExecutable != 0}");
                Console.WriteLine($"{nameof(AccessLevel)} : {AccessLevel}");
                Console.WriteLine($"{nameof(SecurityAccessLevel)} : {SecurityAccessLevel}");
                Console.WriteLine($"{nameof(DataClass)} : {DataClass}");



                Console.WriteLine($"{qualifierName} - ReqBytes: {RequestBytes_Count}, P: {P_Count}, Q: {Q_Count}, R: {R_Count}, S: {S_Count}, T: {T_Count}, Preparation: {U_prep_Count}, V: {V_Count}, W: {W_Count}, X: {X_Count}, Y: {Y_Count}, Z: {Z_Count}, DSC {DiagServiceCodeCount}");
                Console.WriteLine($"at 0x{baseAddress:X}, W @ 0x{W_Offset:X}, DSC @ 0x{DiagServiceCodeOffset:X}");
                Console.WriteLine($"ReqBytes: {BitUtility.BytesToHex(RequestBytes)}");
            }
            */
            //Console.WriteLine($"{qualifierName} - O: {RequestBytes_Count}, P: {P_Count}, Q: {Q_Count}, R: {R_Count}, S: {S_Count}, T: {T_Count}, U: {U_Count}, V: {V_Count}, W: {W_Count}, X: {X_Count}, Y: {Y_Count}, Z: {Z_Count}, DSC {DiagServiceCodeCount}");

            
            byte[] dscPool = parentEcu.ParentContainer.CaesarCFFHeader.DSCPool;
            long dscTableBaseAddress = BaseAddress + DiagServiceCodeOffset;

            using (BinaryReader dscPoolReader = new BinaryReader(new MemoryStream(dscPool)))
            {
                for (int dscIndex = 0; dscIndex < DiagServiceCodeCount; dscIndex++) 
                {
                    reader.BaseStream.Seek(dscTableBaseAddress + (4 * dscIndex), SeekOrigin.Begin);
                    long dscEntryBaseAddress = reader.ReadInt32() + dscTableBaseAddress;
                    reader.BaseStream.Seek(dscEntryBaseAddress, SeekOrigin.Begin);

                    ulong dscEntryBitflags = reader.ReadUInt16();
                    uint idk1 = CaesarReader.ReadBitflagUInt8(ref dscEntryBitflags, reader);
                    uint idk2 = CaesarReader.ReadBitflagUInt8(ref dscEntryBitflags, reader);
                    int dscPoolOffset = CaesarReader.ReadBitflagInt32(ref dscEntryBitflags, reader);
                    string dscQualifier = CaesarReader.ReadBitflagStringWithReader(ref dscEntryBitflags, reader, dscEntryBaseAddress);

                    dscPoolReader.BaseStream.Seek(dscPoolOffset * 8, SeekOrigin.Begin);
                    long dscRecordOffset = dscPoolReader.ReadInt32() + parentEcu.ParentContainer.CaesarCFFHeader.DscBlockOffset;
                    int dscRecordSize = dscPoolReader.ReadInt32();

                    reader.BaseStream.Seek(dscRecordOffset, SeekOrigin.Begin);

                    // Console.WriteLine($"DSC {qualifierName} @ 0x{dscTableBaseAddress:X8} {idk1}/{idk2} pool @ 0x{dscPoolOffset:X}, name: {dscQualifier}");
                    byte[] dscBytes = reader.ReadBytes(dscRecordSize);
#if DEBUG
                    //string dscName = $"{parentEcu.Qualifier}_{Qualifier}_{dscIndex}.pal";
                    //Console.WriteLine($"Exporting DSC: {dscName}");
                    //File.WriteAllBytes(dscName, dscBytes);
#endif
                    // at this point, the DSC binary is available in dscBytes, intended for use in DSCContext (but is currently unimplemented)
                    // Console.WriteLine($"DSC actual at 0x{dscRecordOffset:X}, size=0x{dscRecordSize:X}\n");
                }

            }

        }

        public string GetDescription()
        {
            return Language.GetString(Description_CTF);
        }
        public string GetName()
        {
            return Language.GetString(Name_CTF);
        }

        public long GetCALInt16Offset(BinaryReader reader) 
        {
            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);

            ulong bitflags = reader.ReadUInt32();
            ulong bitflagExtended = reader.ReadUInt32();

            CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress); // Qualifier
            CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); // Name
            CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); // Description
            CaesarReader.ReadBitflagUInt16(ref bitflags, reader); // Type
            CaesarReader.ReadBitflagUInt16(ref bitflags, reader); // IsExecutable 
            if (CaesarReader.CheckAndAdvanceBitflag(ref bitflags))
            {
                return reader.BaseStream.Position;
            }
            else 
            {
                return -1;
            }
        }


        public void PrintDebug() 
        {
            Console.WriteLine($"{Qualifier} - ReqBytes: {RequestBytes_Count}, P: {P_Count}, Q: {Q_Count}, R: {R_Count}, S: {S_Count}, ComParams: {T_ComParam_Count}, Preparation: {U_prep_Count}, V: {V_Count}, OutPres: {W_OutPres_Count}, X: {X_Count}, Y: {Y_Count}, Z: {Z_Count}, DSC {DiagServiceCodeCount}, field50: {Field50}");
            Console.WriteLine($"BaseAddress @ 0x{BaseAddress:X}, NR: {NegativeResponseName}");
            Console.WriteLine($"V @ 0x{BaseAddress + V_Offset:X}, count: {V_Count}");
        }
    }
}




/*
// originally EnvironmentContext, removed because of overlap
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Caesar
{
    public class EnvironmentContext
    {
        // see : const char *__cdecl DIGetComfortErrorCode(DI_ECUINFO *ecuh, unsigned int dtcIndex)
        public string Qualifier;

        public long BaseAddress;
        public int PoolIndex;
        public int Name_CTF;
        public int Description_CTF;
        public int ServiceTypeMaybe;
        public int AccessLevelType_Maybe;
        public int AccessLevelType_Maybe2;
        public int PresentationTableCount;
        public int PresentationTableOffset;
        public int PresentationTableRowSize_Maybe; // see diagservice for similar layout, seems unused (uint16)

        public ECU ParentECU;
        CTFLanguage Language;

        public EnvironmentContext(BinaryReader reader, CTFLanguage language, long baseAddress, int poolIndex, ECU parentEcu)
        {
            ParentECU = parentEcu;
            PoolIndex = poolIndex;
            BaseAddress = baseAddress;
            Language = language;
            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);

            // layout seems very similar to DiagService
            ulong bitflags = reader.ReadUInt32();
            ulong bitflagsExtended = reader.ReadUInt32();

            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);
            Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);

            ServiceTypeMaybe = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            AccessLevelType_Maybe = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            AccessLevelType_Maybe2 = CaesarReader.ReadBitflagInt16(ref bitflags, reader);

            // doesn't seem to be set for any files in my library
            for (int i = 0; i < 14; i++) 
            {
                if (CaesarReader.CheckAndAdvanceBitflag(ref bitflags))
                {
                    throw new Exception("Sorry, The parser for EnvironmentContext has encountered an unknown bitflag; please open an issue and indicate your CBF file name.");
                }
            }

            // these describe the table to the presentation
            PresentationTableCount = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            PresentationTableOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            PresentationTableRowSize_Maybe = CaesarReader.ReadBitflagInt16(ref bitflags, reader);

            // ... looks like DiagService?!
        }

        public void PrintDebug()
        {
            Console.WriteLine(Qualifier);
        }
    }
}
*/

================================================
FILE: Caesar/Caesar/ECU.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Caesar
{
    public class ECU
    {
        public string Qualifier;
        public int EcuName_CTF;
        public int EcuDescription_CTF;
        public string EcuXmlVersion;
        public int InterfaceBlockCount;
        public int InterfaceTableOffset;
        public int SubinterfacesCount;
        public int SubinterfacesOffset;
        public string EcuClassName;
        public string UnkStr7;
        public string UnkStr8;

        public int IgnitionRequired;
        public int Unk2;
        public int UnkBlockCount;
        public int UnkBlockOffset;
        public int EcuSgmlSource;
        public int Unk6RelativeOffset;

        private int EcuVariant_BlockOffset; // 1
        private int EcuVariant_EntryCount;
        private int EcuVariant_EntrySize;
        private int EcuVariant_BlockSize;

        private int DiagJob_BlockOffset; // 2
        private int DiagJob_EntryCount;
        private int DiagJob_EntrySize;
        private int DiagJob_BlockSize;

        private int Dtc_BlockOffset; // 3
        private int Dtc_EntryCount;
        private int Dtc_EntrySize;
        private int Dtc_BlockSize;

        private int Env_BlockOffset; // 4
        private int Env_EntryCount;
        private int Env_EntrySize;
        private int Env_BlockSize;

        private int VcDomain_BlockOffset; // 5 , 0x15716
        private int VcDomain_EntryCount; // [1], 43 0x2B
        private int VcDomain_EntrySize; // [2], 12 0xC (multiply with [1] for size), 43*12=516 = 0x204
        private int VcDomain_BlockSize; // [3] unused

        private int Presentations_BlockOffset;
        private int Presentations_EntryCount;
        private int Presentations_EntrySize;
        private int Presentations_BlockSize;

        private int InternalPresentations_BlockOffset; // 31 (formerly InfoPool)
        private int InternalPresentations_EntryCount; // 32
        private int InternalPresentations_EntrySize; // 33
        private int InternalPresentations_BlockSize; // 34

        private int Unk_BlockOffset;
        private int Unk_EntryCount;
        private int Unk_EntrySize;
        private int Unk_BlockSize;

        public int Unk39;

        public List<ECUInterface> ECUInterfaces = new List<ECUInterface>();
        public List<ECUInterfaceSubtype> ECUInterfaceSubtypes = new List<ECUInterfaceSubtype>();
        public List<ECUVariant> ECUVariants = new List<ECUVariant>();

        public List<VCDomain> GlobalVCDs = new List<VCDomain>();
        public List<DTC> GlobalDTCs = new List<DTC>();
        public List<DiagService> GlobalEnvironmentContexts = new List<DiagService>();
        public List<DiagService> GlobalDiagServices = new List<DiagService>();
        public List<DiagPresentation> GlobalPresentations = new List<DiagPresentation>();
        public List<DiagPresentation> GlobalInternalPresentations = new List<DiagPresentation>();

        private long BaseAddress;
        [Newtonsoft.Json.JsonIgnore]
        public CTFLanguage Language;

        [Newtonsoft.Json.JsonIgnore]
        public CaesarContainer ParentContainer;

        byte[] cachedVarcodingPool = new byte[] { };
        byte[] cachedVariantPool = new byte[] { };
        byte[] cachedDiagjobPool = new byte[] { };
        byte[] cachedEcuInfoPool = new byte[] { };
        byte[] cachedPresentationsPool = new byte[] { };
        byte[] cachedInternalPresentationsPool = new byte[] { };
        byte[] cachedEnvPool = new byte[] { };
        byte[] cachedDtcPool = new byte[] { };
        byte[] cachedUnkPool = new byte[] { };

        [Newtonsoft.Json.JsonIgnore]
        public string ECUDescription { get { return Language.GetString(EcuDescription_CTF); } }


        public void Restore(CTFLanguage language, CaesarContainer parentContainer) 
        {
            Language = language;
            ParentContainer = parentContainer;
            foreach (VCDomain vc in GlobalVCDs)
            {
                vc.Restore(language, this);
            }
            foreach (DTC dtc in GlobalDTCs)
            {
                dtc.Restore(language, this);
            }
            foreach (DiagService ds in GlobalDiagServices)
            {
                ds.Restore(language, this);
            }
            foreach (DiagService ds in GlobalEnvironmentContexts)
            {
                ds.Restore(language, this);
            }
            foreach (DiagPresentation pres in GlobalPresentations)
            {
                pres.Restore(language);
            }
            foreach (DiagPresentation pres in GlobalInternalPresentations)
            {
                pres.Restore(language);
            }
            foreach (ECUInterface iface in ECUInterfaces)
            {
                iface.Restore(language);
            }
            foreach (ECUInterfaceSubtype iface in ECUInterfaceSubtypes)
            {
                iface.Restore(language);
            }
            foreach (ECUVariant variant in ECUVariants)
            {
                variant.Restore(language, this);
            }
        }

        public byte[] ReadDiagjobPool(BinaryReader reader)
        {
            if (cachedDiagjobPool.Length == 0)
            {
                cachedDiagjobPool = ReadEcuPool(reader, DiagJob_BlockOffset, DiagJob_EntryCount, DiagJob_EntrySize);
            }
            return cachedDiagjobPool;
        }

        public byte[] ReadVariantPool(BinaryReader reader)
        {
            if (cachedVariantPool.Length == 0)
            {
                cachedVariantPool = ReadEcuPool(reader, EcuVariant_BlockOffset, EcuVariant_EntryCount, EcuVariant_EntrySize);
            }
            return cachedVariantPool;
        }

        public byte[] ReadVarcodingPool(BinaryReader reader)
        {
            if (cachedVarcodingPool.Length == 0)
            {
                cachedVarcodingPool = ReadEcuPool(reader, VcDomain_BlockOffset, VcDomain_EntryCount, VcDomain_EntrySize);
            }
            return cachedVarcodingPool;
        }
        // don't actually know what the proper name is, using "ECUInfo" for now
        public byte[] ReadECUInfoPool(BinaryReader reader)
        {
            if (cachedEcuInfoPool.Length == 0)
            {
                cachedEcuInfoPool = ReadEcuPool(reader, InternalPresentations_BlockOffset, InternalPresentations_EntryCount, InternalPresentations_EntrySize);
            }
            return cachedEcuInfoPool;
        }
        public byte[] ReadECUPresentationsPool(BinaryReader reader)
        {
            if (cachedPresentationsPool.Length == 0)
            {
                cachedPresentationsPool = ReadEcuPool(reader, Presentations_BlockOffset, Presentations_EntryCount, Presentations_EntrySize);
            }
            return cachedPresentationsPool;
        }
        public byte[] ReadECUInternalPresentationsPool(BinaryReader reader)
        {
            if (cachedInternalPresentationsPool.Length == 0)
            {
                cachedInternalPresentationsPool = ReadEcuPool(reader, InternalPresentations_BlockOffset, InternalPresentations_EntryCount, InternalPresentations_EntrySize);
            }
            return cachedInternalPresentationsPool;
        }
        public byte[] ReadECUEnvPool(BinaryReader reader)
        {
            if (cachedEnvPool.Length == 0)
            {
                cachedEnvPool = ReadEcuPool(reader, Env_BlockOffset, Env_EntryCount, Env_EntrySize);
            }
            return cachedEnvPool;
        }
        public byte[] ReadECUUnkPool (BinaryReader reader)
        {
            if (cachedUnkPool.Length == 0)
            {
                cachedUnkPool = ReadEcuPool(reader, Unk_BlockOffset, Unk_EntryCount, Unk_EntrySize);
            }
            return cachedUnkPool;
        }

        public byte[] ReadECUDtcPool(BinaryReader reader)
        {
            if (cachedDtcPool.Length == 0)
            {
                cachedDtcPool = ReadEcuPool(reader, Dtc_BlockOffset, Dtc_EntryCount, Dtc_EntrySize);
            }
            return cachedDtcPool;
        }

        public byte[] ReadEcuPool(BinaryReader reader, long addressToReadFrom, int multiplier1, int multiplier2) 
        {
            reader.BaseStream.Seek(addressToReadFrom, SeekOrigin.Begin);
            return reader.ReadBytes(multiplier1 * multiplier2);
        }

        public ECU() { }

        public ECU(BinaryReader reader, CTFLanguage language, CFFHeader header, long baseAddress, CaesarContainer parentContainer)  
        {
            ParentContainer = parentContainer;
            BaseAddress = baseAddress;
            Language = language;
            // Read 32+16 bits
            ulong ecuBitFlags = reader.ReadUInt32();
            // after exhausting the 32 bits, load these additional 16 bits
            ulong ecuBitFlagsExtended = reader.ReadUInt16();

            // Console.WriteLine($"ECU bitflags: {ecuBitFlags:X}");

            // advancing forward to ecuBase + 10
            int ecuHdrIdk1 = reader.ReadInt32(); // no idea
            // Console.WriteLine($"Skipping: {ecuHdrIdk1:X8}");

            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);
            EcuName_CTF = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader, -1);
            EcuDescription_CTF = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader, -1);
            EcuXmlVersion = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);
            InterfaceBlockCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            InterfaceTableOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            SubinterfacesCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            SubinterfacesOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            EcuClassName = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);
            UnkStr7 = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);
            UnkStr8 = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);

            int dataBufferOffsetRelativeToFile = header.StringPoolSize + StubHeader.StubHeaderSize + header.CffHeaderSize + 4;
            // Console.WriteLine($"{nameof(dataBufferOffsetRelativeToFile)} : 0x{dataBufferOffsetRelativeToFile:X}");

            IgnitionRequired = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader);
            Unk2 = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader);
            UnkBlockCount = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader);
            UnkBlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            EcuSgmlSource = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader);
            Unk6RelativeOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            EcuVariant_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            EcuVariant_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            EcuVariant_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 10
            EcuVariant_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            DiagJob_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            DiagJob_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            DiagJob_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 14
            DiagJob_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            Dtc_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            Dtc_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Dtc_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 12
            Dtc_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            Env_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            Env_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Env_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 8

            // bitflags will be exhausted at this point, load the extended bitflags
            ecuBitFlags = ecuBitFlagsExtended;

            Env_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            VcDomain_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            VcDomain_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            VcDomain_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 12
            VcDomain_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            Presentations_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            Presentations_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Presentations_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 8
            Presentations_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            InternalPresentations_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            InternalPresentations_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            InternalPresentations_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 8
            InternalPresentations_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            Unk_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            Unk_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Unk_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Unk_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            Unk39 = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            // read ecu's supported interfaces and subtypes

            // try to read interface block from the interface buffer table
            // this address is relative to the definitions block
            long interfaceTableAddress = BaseAddress + InterfaceTableOffset;
            // Console.WriteLine($"Interface table address: {interfaceTableAddress:X}, given offset: {interfaceTableOffset:X}");

            ECUInterfaces = new List<ECUInterface>();
            for (int interfaceBufferIndex = 0; interfaceBufferIndex < InterfaceBlockCount; interfaceBufferIndex++)
            {
                // Console.WriteLine($"Parsing interface {interfaceBufferIndex + 1}/{interfaceBlockCount}");

                // find our interface block offset
                reader.BaseStream.Seek(interfaceTableAddress + (interfaceBufferIndex * 4), SeekOrigin.Begin);
                // seek to the actual block (ambiguity: is this relative to the interface table or the current array?)
                int interfaceBlockOffset = reader.ReadInt32();

                long ecuInterfaceBaseAddress = interfaceTableAddress + interfaceBlockOffset;

                ECUInterface ecuInterface = new ECUInterface(reader, ecuInterfaceBaseAddress);
                ECUInterfaces.Add(ecuInterface);
            }

            // try to read interface subtype block from the interface buffer table
            // this address is relative to the definitions block
            ECUInterfaceSubtypes = new List<ECUInterfaceSubtype>();
            long ctTableAddress = BaseAddress + SubinterfacesOffset;
            // Console.WriteLine($"Interface subtype table address: {ctTableAddress:X}, given offset: {ecuChildTypesOffset:X}");
            for (int ctBufferIndex = 0; ctBufferIndex < SubinterfacesCount; ctBufferIndex++)
            {
                // Console.WriteLine($"Parsing interface subtype {ctBufferIndex + 1}/{ecuNumberOfEcuChildTypes}");
                // find our ct block offset
                reader.BaseStream.Seek(ctTableAddress + (ctBufferIndex * 4), SeekOrigin.Begin);
                // seek to the actual block (ambiguity: is this relative to the ct table or the current array?)
                int actualBlockOffset = reader.ReadInt32();
                long ctBaseAddress = ctTableAddress + actualBlockOffset;

                ECUInterfaceSubtype ecuInterfaceSubtype = new ECUInterfaceSubtype(reader, ctBaseAddress, ctBufferIndex, language);
                ECUInterfaceSubtypes.Add(ecuInterfaceSubtype);
            }

            // dependency of variants
            CreatePresentations(reader, language);
            CreateInternalPresentations(reader, language);
            // requires presentations
            CreateEnvironments(reader, language);
            CreateDiagServices(reader, language);
            // dtc has xrefs to envs
            CreateDTCs(reader, language);
            CreateVCDomains(reader, language);

            CreateEcuVariants(reader, language);
            //PrintDebug();
        }

        public void CreateDiagServices(BinaryReader reader, CTFLanguage language)
        {
            byte[] diagjobPool = ReadDiagjobPool(reader);
            // arrays since list has become too expensive
            DiagService[] globalDiagServices = new DiagService[DiagJob_EntryCount];


            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(diagjobPool)))
            {
                for (int diagjobIndex = 0; diagjobIndex < DiagJob_EntryCount; diagjobIndex++)
                {
                    int offset = poolReader.ReadInt32();
                    int size = poolReader.ReadInt32();
                    uint crc = poolReader.ReadUInt32();
                    uint config = poolReader.ReadUInt16();
                    long diagjobBaseAddress = offset + DiagJob_BlockOffset;
                    // Console.WriteLine($"DJ @ {offset:X} with size {size:X}");

                    DiagService dj = new DiagService(reader, language, diagjobBaseAddress, diagjobIndex, this);
                    // GlobalDiagServices.Add(dj);
                    globalDiagServices[diagjobIndex] = dj;
                }
            }

            GlobalDiagServices = new List<DiagService>(globalDiagServices);
        }
        public void CreateDTCs(BinaryReader reader, CTFLanguage language)
        {
            byte[] dtcPool = ReadECUDtcPool(reader);
            DTC[] globalDtcs = new DTC[Dtc_EntryCount];
            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(dtcPool)))
            {
                for (int dtcIndex = 0; dtcIndex < Dtc_EntryCount; dtcIndex++)
                {
                    int offset = poolReader.ReadInt32();
                    int size = poolReader.ReadInt32();
                    uint crc = poolReader.ReadUInt32();
                    long dtcBaseAddress = offset + Dtc_BlockOffset;

                    DTC dtc = new DTC(reader, language, dtcBaseAddress, dtcIndex, this);
                    globalDtcs[dtcIndex] = dtc;
                }
            }
            GlobalDTCs = new List<DTC>(globalDtcs);
        }

        public void CreateVCDomains(BinaryReader reader, CTFLanguage language) 
        {
            byte[] vcPool = ReadVarcodingPool(reader);
            VCDomain[] globalVCDs = new VCDomain[VcDomain_EntryCount];
            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(vcPool)))
            {
                for (int vcdIndex = 0; vcdIndex < VcDomain_EntryCount; vcdIndex++)
                {
                    int entryOffset = poolReader.ReadInt32();
                    int entrySize = poolReader.ReadInt32();
                    uint entryCrc = poolReader.ReadUInt32();
                    long vcdBlockAddress = entryOffset + VcDomain_BlockOffset;
                    VCDomain vcd = new VCDomain(reader, language, vcdBlockAddress, vcdIndex, this);
                    globalVCDs[vcdIndex] = vcd;
                }
            }
            GlobalVCDs = new List<VCDomain>(globalVCDs);
        }

        public void CreateEnvironments(BinaryReader reader, CTFLanguage language)
        {
            /*
            byte[] envPool = ReadECUEnvPool(reader);
            EnvironmentContext[] globalEnvs = new EnvironmentContext[Env_EntryCount];
            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(envPool)))
            {
                for (int envIndex = 0; envIndex < Env_EntryCount; envIndex++)
                {
                    int offset = poolReader.ReadInt32();
                    int size = poolReader.ReadInt32();
                    long envBaseAddress = offset + Env_BlockOffset;

                    // Console.WriteLine($"0x{envBaseAddress:X}");
                    EnvironmentContext env = new EnvironmentContext(reader, language, envBaseAddress, envIndex, this);
                    globalEnvs[envIndex] = env;
                }
            }
            GlobalEnvironmentContexts = new List<EnvironmentContext>(globalEnvs);
            */
            byte[] envPool = ReadECUEnvPool(reader);
            DiagService[] globalEnvs = new DiagService[Env_EntryCount];
            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(envPool)))
            {
                for (int envIndex = 0; envIndex < Env_EntryCount; envIndex++)
                {
                    int offset = poolReader.ReadInt32();
                    int size = poolReader.ReadInt32();
                    long envBaseAddress = offset + Env_BlockOffset;

                    // Console.WriteLine($"0x{envBaseAddress:X}");
                    DiagService env = new DiagService(reader, language, envBaseAddress, envIndex, this);
                    globalEnvs[envIndex] = env;
                }
            }
            GlobalEnvironmentContexts = new List<DiagService>(globalEnvs);
        }
        public void CreateUnk(BinaryReader reader, CTFLanguage language)
        {
            byte[] unkPool = ReadECUUnkPool(reader);
            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(unkPool)))
            {
                for (int unkIndex = 0; unkIndex < Unk_EntryCount; unkIndex++)
                {
                }
            }
        }
        public void CreatePresentations(BinaryReader reader, CTFLanguage language)
        {
            byte[] presentationsPool = ReadECUPresentationsPool(reader);
            // arrays since list has become too expensive
            // DiagService[] globalDiagServices = new DiagService[DiagJob_EntryCount];
            DiagPresentation[] globalPresentations = new DiagPresentation[Presentations_EntryCount];

            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(presentationsPool)))
            {
                for (int presentationsIndex = 0; presentationsIndex < Presentations_EntryCount; presentationsIndex++)
                {

                    int offset = poolReader.ReadInt32();
                    int size = poolReader.ReadInt32();

                    long presentationsBaseAddress = offset + Presentations_BlockOffset;
                    // string offsetLog = $"Pres @ 0x{offset:X} with size 0x{size:X} base 0x{presentationsBaseAddress:X}";

                    DiagPresentation pres = new DiagPresentation(reader, presentationsBaseAddress, presentationsIndex, language);
                    globalPresentations[presentationsIndex] = pres;
                }
                // Console.WriteLine($"Entry count/size for presentations : {Presentations_EntryCount}, {Presentations_EntrySize}");
            }
            GlobalPresentations = new List<DiagPresentation>(globalPresentations);
        }
        public void CreateInternalPresentations(BinaryReader reader, CTFLanguage language)
        {
            byte[] internalPresentationsPool = ReadECUInternalPresentationsPool(reader);
            DiagPresentation[] globalInternalPresentations = new DiagPresentation[InternalPresentations_EntryCount];

            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(internalPresentationsPool)))
            {
                for (int internalPresentationsIndex = 0; internalPresentationsIndex < InternalPresentations_EntryCount; internalPresentationsIndex++)
                {
                    int offset = poolReader.ReadInt32();
                    int size = poolReader.ReadInt32();

                    long internalPresentationsBaseAddress = offset + InternalPresentations_BlockOffset;
                    DiagPresentation pres = new DiagPresentation(reader, internalPresentationsBaseAddress, internalPresentationsIndex, language);
                    globalInternalPresentations[internalPresentationsIndex] = pres;
                }
            }
            GlobalInternalPresentations = new List<DiagPresentation>(globalInternalPresentations);
        }
        public void CreateEcuVariants(BinaryReader reader, CTFLanguage language) 
        {
            ECUVariants.Clear();
            byte[] ecuVariantPool = ReadVariantPool(reader);

            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(ecuVariantPool)))
            {
                for (int ecuVariantIndex = 0; ecuVariantIndex < EcuVariant_EntryCount; ecuVariantIndex++)
                {
                    poolReader.BaseStream.Seek(ecuVariantIndex * EcuVariant_EntrySize, SeekOrigin.Begin);
                    
                    int entryOffset = poolReader.ReadInt32();
                    int entrySize = poolReader.ReadInt32();
                    ushort poolEntryAttributes = poolReader.ReadUInt16();
                    long variantBlockAddress = entryOffset + EcuVariant_BlockOffset;

                    ECUVariant variant = new ECUVariant(reader, this, language, variantBlockAddress, entrySize);
                    ECUVariants.Add(variant);
                    // Console.WriteLine($"Variant Entry @ 0x{entryOffset:X} with size 0x{entrySize:X} and CRC {poolEntryAttributes:X8}, abs addr {variantBlockAddress:X8}");

#if DEBUG
                    int resultLimit = 1999;
                    if (ecuVariantIndex >= resultLimit)
                    {
                        Console.WriteLine($"Breaking prematurely to create only {resultLimit} variant(s) (debug)");
                        break;
                    }
#endif
                }
            }
        }

        public void PrintDebug()
        {
            Console.WriteLine($"ECU Name: {Qualifier}");
            Console.WriteLine($"{nameof(EcuName_CTF)} : {EcuName_CTF}");
            Console.WriteLine($"{nameof(EcuDescription_CTF)} : {EcuDescription_CTF}");
            Console.WriteLine($"ECU ecuXmlVersion: {EcuXmlVersion}");
            Console.WriteLine($"{nameof(InterfaceBlockCount)} : {InterfaceBlockCount}");
            Console.WriteLine($"{nameof(InterfaceTableOffset)} : 0x{InterfaceTableOffset:X}");
            Console.WriteLine($"{nameof(SubinterfacesCount)} : {SubinterfacesCount}");
            Console.WriteLine($"{nameof(SubinterfacesOffset)} : {SubinterfacesOffset}");
            Console.WriteLine($"ECU ecuClassName: {EcuClassName}");
            Console.WriteLine($"ECU ecuIdk7: {UnkStr7}");
            Console.WriteLine($"ECU ecuIdk8: {UnkStr8}");


            Console.WriteLine($"{nameof(IgnitionRequired)} : {IgnitionRequired}");
            
            Console.WriteLine($"{nameof(Unk2)} : {Unk2}"); 

            Console.WriteLine($"{nameof(UnkBlockCount)} : {UnkBlockCount}");
            Console.WriteLine($"{nameof(UnkBlockOffset)} : {UnkBlockOffset}");
            
            Console.WriteLine($"{nameof(EcuSgmlSource)} : {EcuSgmlSource}");
            Console.WriteLine($"{nameof(Unk6RelativeOffset)} : 0x{Unk6RelativeOffset:X}");
            
            Console.WriteLine($"{nameof(EcuVariant_BlockOffset)} : 0x{EcuVariant_BlockOffset:X}");
            Console.WriteLine($"{nameof(EcuVariant_EntryCount)} : {EcuVariant_EntryCount}");
            Console.WriteLine($"{nameof(EcuVariant_EntrySize)} : {EcuVariant_EntrySize}");
            Console.WriteLine($"{nameof(EcuVariant_BlockSize)} : 0x{EcuVariant_BlockSize:X}");
            Console.WriteLine($"{nameof(DiagJob_BlockOffset)} : 0x{DiagJob_BlockOffset:X}");
            Console.WriteLine($"{nameof(DiagJob_EntryCount)} : {DiagJob_EntryCount}");
            Console.WriteLine($"{nameof(DiagJob_EntrySize)} : {DiagJob_EntrySize}");
            Console.WriteLine($"{nameof(DiagJob_BlockSize)} : 0x{DiagJob_BlockSize:X}");
            Console.WriteLine($"{nameof(Dtc_BlockOffset)} : 0x{Dtc_BlockOffset:X}");
            Console.WriteLine($"{nameof(Dtc_EntryCount)} : {Dtc_EntryCount}");
            Console.WriteLine($"{nameof(Dtc_EntrySize)} : {Dtc_EntrySize}");
            Console.WriteLine($"{nameof(Dtc_BlockSize)} : 0x{Dtc_BlockSize:X}");
            Console.WriteLine($"{nameof(Env_BlockOffset)} : 0x{Env_BlockOffset:X}");
            Console.WriteLine($"{nameof(Env_EntryCount)} : {Env_EntryCount}");
            Console.WriteLine($"{nameof(Env_EntrySize)} : {Env_EntrySize}");

            // Console.WriteLine("--- bitflag load 2 ---");

            Console.WriteLine($"{nameof(Env_BlockSize)} : 0x{Env_BlockSize:X}");
            Console.WriteLine($"{nameof(VcDomain_BlockOffset)} : 0x{VcDomain_BlockOffset:X}");
            Console.WriteLine($"{nameof(VcDomain_EntryCount)} : {VcDomain_EntryCount}");
            Console.WriteLine($"{nameof(VcDomain_EntrySize)} : {VcDomain_EntrySize}");
            Console.WriteLine($"{nameof(VcDomain_BlockSize)} : 0x{VcDomain_BlockSize:X}");
            Console.WriteLine($"{nameof(Presentations_BlockOffset)} : 0x{Presentations_BlockOffset:X}");
            Console.WriteLine($"{nameof(Presentations_EntryCount)} : {Presentations_EntryCount}");
            Console.WriteLine($"{nameof(Presentations_EntrySize)} : {Presentations_EntrySize}");
            Console.WriteLine($"{nameof(Presentations_BlockSize)} : 0x{Presentations_BlockSize:X}");
            Console.WriteLine($"{nameof(InternalPresentations_BlockOffset)} : 0x{InternalPresentations_BlockOffset:X}");
            Console.WriteLine($"{nameof(InternalPresentations_EntryCount)} : {InternalPresentations_EntryCount}");
            Console.WriteLine($"{nameof(InternalPresentations_EntrySize)} : {InternalPresentations_EntrySize}");
            Console.WriteLine($"{nameof(InternalPresentations_BlockSize)} : 0x{InternalPresentations_BlockSize:X}");
            Console.WriteLine($"{nameof(Unk_BlockOffset)} : 0x{Unk_BlockOffset:X}");
            Console.WriteLine($"{nameof(Unk_EntryCount)} : {Unk_EntryCount}");
            Console.WriteLine($"{nameof(Unk_EntrySize)} : {Unk_EntrySize}");
            Console.WriteLine($"{nameof(Unk_BlockSize)} : {Unk_BlockSize}");
            Console.WriteLine($"{nameof(Unk39)} : {Unk39}");
        }
    }
}

/*
 example env records

ENV_48_Data_Record_1_StdEnvData
ENV_56_StdEnv_OccurenceFlag
ENV_64_StdEnv_OriginalOdometerValue
ENV_80_StdEnv_MostRecentOdometerValue
ENV_96_StdEnv_FrequencyCounter
ENV_104_StdEnv_OperationCycleCounter
ENV_112_Data_Record_2_CommonEnvData
ENV_120_CommonEnv_StorageSequence
ENV_128_Data_Record_3_First_Occurrence
ENV_136_First_SIGNALS_xSet1
ENV_136_First_SIGNALS_xSet2
*/


================================================
FILE: Caesar/Caesar/ECUInterface.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Caesar
{
    public class ECUInterface
    {
        public string Qualifier;
        public int Name_CTF;
        public int Description_CTF;
        public string VersionString;
        public int Version;
        private int ComParamCount;
        private int ComParamListOffset;
        public int Unk6;
        

        public List<string> ComParameterNames = new List<string>();

        private CTFLanguage Language;
        private long BaseAddress;

        public void Restore(CTFLanguage language) 
        {
            Language = language;
        }

        public ECUInterface() { }

        public ECUInterface(BinaryReader reader, long baseAddress)
        {
            BaseAddress = baseAddress;
            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);

            // we can now properly operate on the interface block
            ulong interfaceBitflags = reader.ReadUInt32();

            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref interfaceBitflags, reader, BaseAddress);
            Name_CTF = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader, -1);
            Description_CTF = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader, -1);
            VersionString = CaesarReader.ReadBitflagStringWithReader(ref interfaceBitflags, reader, BaseAddress);
            Version = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader);
            ComParamCount = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader);
            ComParamListOffset = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader);
            Unk6 = CaesarReader.ReadBitflagInt16(ref interfaceBitflags, reader);


            long comparamFileOffset = ComParamListOffset + BaseAddress;
            // Console.WriteLine($"interface string table offset from definition block : {interfaceStringTableOffset_fromDefinitionBlock:X}");

            for (int interfaceStringIndex = 0; interfaceStringIndex < ComParamCount; interfaceStringIndex++)
            {
                // seek to string pointer
                reader.BaseStream.Seek(comparamFileOffset + (interfaceStringIndex * 4), SeekOrigin.Begin);
                // from pointer, seek to string
                long interfaceStringReadoutPtr = reader.ReadInt32() + comparamFileOffset;
                reader.BaseStream.Seek(interfaceStringReadoutPtr, SeekOrigin.Begin);
                string comParameter = CaesarReader.ReadStringFromBinaryReader(reader);
                ComParameterNames.Add(comParameter);
            }
        }

        public void PrintDebug() 
        {
            Console.WriteLine($"{nameof(Qualifier)} : {Qualifier}");
            Console.WriteLine($"{nameof(Name_CTF)} : {Name_CTF}");
            Console.WriteLine($"{nameof(Description_CTF)} : {Description_CTF}");
            Console.WriteLine($"{nameof(VersionString)} : {VersionString}");
            Console.WriteLine($"{nameof(Version)} : {Version}");
            Console.WriteLine($"{nameof(ComParamCount)} : {ComParamCount}");
            Console.WriteLine($"{nameof(ComParamListOffset)} : 0x{ComParamListOffset:X}");
            Console.WriteLine($"{nameof(Unk6)} : {Unk6}");

            foreach (string comParameter in ComParameterNames)
            {
                Console.WriteLine($"InterfaceComParameter: {comParameter}");
            }
        }
    }
}


================================================
FILE: Caesar/Caesar/ECUInterfaceSubtype.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;


namespace Caesar
{
    public class ECUInterfaceSubtype
    {
        public enum ParamName 
        {
            CP_BAUDRATE,
            CP_GLOBAL_REQUEST_CANIDENTIFIER,
            CP_FUNCTIONAL_REQUEST_CANIDENTIFIER,
            CP_REQUEST_CANIDENTIFIER,
            CP_RESPONSE_CANIDENTIFIER,
            CP_PARTNUMBERID,
            CP_PARTBLOCK,
            CP_HWVERSIONID,
            CP_SWVERSIONID,
            CP_SWVERSIONBLOCK,
            CP_SUPPLIERID,
            CP_SWSUPPLIERBLOCK,
            CP_ADDRESSMODE,
            CP_ADDRESSEXTENSION,
            CP_ROE_RESPONSE_CANIDENTIFIER,
            CP_USE_TIMING_RECEIVED_FROM_ECU,
            CP_STMIN_SUG,
            CP_BLOCKSIZE_SUG,
            CP_P2_TIMEOUT,
            CP_S3_TP_PHYS_TIMER,
            CP_S3_TP_FUNC_TIMER,
            CP_BR_SUG,
            CP_CAN_TRANSMIT,
            CP_BS_MAX,
            CP_CS_MAX,
            CPI_ROUTINECOUNTER,
            CP_REQREPCOUNT,
            // looks like outliers?
            CP_P2_EXT_TIMEOUT_7F_78,
            CP_P2_EXT_TIMEOUT_7F_21,
        }

        public string Qualifier;
        public int Name_CTF;
        public int Description_CTF;

        public int Unk3;
        public int Unk4;

        public int Unk5;
        public int Unk6;
        public int Unk7;

        public int Unk8;
        public int Unk9;
        public int Unk10; // might be signed

        private long BaseAddress;
        private int Index;

        public List<ComParameter> CommunicationParameters = new List<ComParameter>();
        private CTFLanguage Language;

        public void Restore(CTFLanguage language) 
        {
            Language = language;
            foreach (ComParameter cp in CommunicationParameters) 
            {
                cp.Restore(language);
            }
        }

        public ECUInterfaceSubtype() { }

        public ECUInterfaceSubtype(BinaryReader reader, long baseAddress, int index, CTFLanguage language)
        {
            Index = index;
            BaseAddress = baseAddress;
            Language = language;
            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);
            // we can now properly operate on the interface block
            ulong ctBitflags = reader.ReadUInt32();

            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref ctBitflags, reader, BaseAddress);
            Name_CTF = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader, -1);
            Description_CTF = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader, -1);

            Unk3 = CaesarReader.ReadBitflagInt16(ref ctBitflags, reader);
            Unk4 = CaesarReader.ReadBitflagInt16(ref ctBitflags, reader);

            Unk5 = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader);
            Unk6 = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader);
            Unk7 = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader);

            Unk8 = CaesarReader.ReadBitflagUInt8(ref ctBitflags, reader);
            Unk9 = CaesarReader.ReadBitflagUInt8(ref ctBitflags, reader);
            Unk10 = CaesarReader.ReadBitflagInt8(ref ctBitflags, reader); // might be signed
        }

        public ComParameter GetComParameterByName(string paramName) 
        {
            return CommunicationParameters.Find(x => x.ParamName == paramName);
        }
        public int GetComParameterValue(ParamName name)
        {
            return GetComParameterByName(name.ToString()).ComParamValue;
        }
        public bool GetComParameterValue(ParamName name, out int result)
        {
            ComParameter param = GetComParameterByName(name.ToString());
            if (param is null)
            {
                result = 0;
                return false;
            }
            else 
            {
                result = param.ComParamValue;
                return true;
            }
        }

        public void PrintDebug()
        {
            Console.WriteLine($"iface subtype: @ 0x{BaseAddress:X}");
            Console.WriteLine($"{nameof(Name_CTF)} : {Name_CTF}");
            Console.WriteLine($"{nameof(Description_CTF)} : {Description_CTF}");
            Console.WriteLine($"{nameof(Unk3)} : {Unk3}");
            Console.WriteLine($"{nameof(Unk4)} : {Unk4}");
            Console.WriteLine($"{nameof(Unk5)} : {Unk5}");
            Console.WriteLine($"{nameof(Unk6)} : {Unk6}");
            Console.WriteLine($"{nameof(Unk7)} : {Unk7}");
            Console.WriteLine($"{nameof(Unk8)} : {Unk8}");
            Console.WriteLine($"{nameof(Unk9)} : {Unk9}");
            Console.WriteLine($"{nameof(Unk10)} : {Unk10}");
            Console.WriteLine($"CT: {Qualifier}");
        }
    }
}


================================================
FILE: Caesar/Caesar/ECUVariant.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Caesar
{
    public class ECUVariant
    {
        public string Qualifier;
        public int Name_CTF;
        public int Description_CTF;
        public string UnkStr1;
        public string UnkStr2;
        public int Unk1;
        
        private int MatchingPatternCount; // A
        private int MatchingPatternOffset;
        private int SubsectionB_Count; // B
        private int SubsectionB_Offset;
        private int ComParamsCount; // C
        private int ComParamsOffset;
        private int DiagServiceCode_Count; // D : DSC
        private int DiagServiceCode_Offset;
        private int DiagServicesCount; // E
        private int DiagServicesOffset;
        private int DTC_Count; // F
        private int DTC_Offset;
        private int EnvironmentCtx_Count; // G
        private int EnvironmentCtx_Offset;
        private int Xref_Count; // H
        private int Xref_Offset;
        private int VCDomainsCount; // I
        private int VCDomainsOffset;

        public string NegativeResponseName;
        public int UnkByte;

        public List<int> VCDomainPoolOffsets = new List<int>();
        public List<int> DiagServicesPoolOffsets = new List<int>();
        public List<Tuple<int, int, int>> DTCsPoolOffsetsWithBounds = new List<Tuple<int, int, int>>();
        public List<int> EnvironmentContextsPoolOffsets = new List<int>();

        public List<ECUVariantPattern> VariantPatterns = new List<ECUVariantPattern>();
        public int[] Xrefs = new int[] { };

        // these should be manually deserialized by creating references back to the parent ECU

        [Newtonsoft.Json.JsonIgnore]
        public List<VCDomain> VCDomains = new List<VCDomain>();
        [Newtonsoft.Json.JsonIgnore]
        public DiagService[] DiagServices = new DiagService[] { };
        [Newtonsoft.Json.JsonIgnore]
        public DTC[] DTCs = new DTC[] { };
        [Newtonsoft.Json.JsonIgnore]
        public DiagService[] EnvironmentContexts = new DiagService[] { };

        public long BaseAddress;
        [Newtonsoft.Json.JsonIgnore]
        public ECU ParentECU;

        [Newtonsoft.Json.JsonIgnore]
        private CTFLanguage Language;

        public void Restore(CTFLanguage language, ECU parentEcu) 
        {
            Language = language;
            ParentECU = parentEcu;

            CreateVCDomains(parentEcu, language);
            CreateDiagServices(parentEcu, language);
            CreateDTCs(parentEcu, language);
            CreateEnvironmentContexts(parentEcu, language);

            /*
            // no restoring required
            foreach (ECUVariantPattern vp in VariantPatterns) 
            {
                vp.Restore();
            }
            */
            // CreateComParameters(reader, parentEcu); // already serialized in json
        }

        public ECUVariant() { }

        public ECUVariant(BinaryReader reader, ECU parentEcu, CTFLanguage language, long baseAddress, int blockSize)
        {
            // int __usercall DIIFindVariantByECUID@<eax>(ECU_VARIANT *a1@<ebx>, _DWORD *a2, int a3, __int16 a4, int a5)

            BaseAddress = baseAddress;
            ParentECU = parentEcu;
            Language = language;
            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);
            byte[] variantBytes = reader.ReadBytes(blockSize);

            using (BinaryReader variantReader = new BinaryReader(new MemoryStream(variantBytes, 0, variantBytes.Length, false, true)))
            {
                ulong bitFlags = variantReader.ReadUInt32();
                int skip = variantReader.ReadInt32();

                Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, variantReader);
                Name_CTF = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader, -1);
                Description_CTF = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader, -1);
                UnkStr1 = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, variantReader);
                UnkStr2 = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, variantReader);

                Unk1 = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 1 
                MatchingPatternCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 2 
                MatchingPatternOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 3 
                SubsectionB_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 4 
                SubsectionB_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 5 
                ComParamsCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 6 
                ComParamsOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 7 
                DiagServiceCode_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 8 
                DiagServiceCode_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 9 
                DiagServicesCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 10 
                DiagServicesOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 11 
                DTC_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 12 
                DTC_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 13 
                EnvironmentCtx_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 14
                EnvironmentCtx_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 15 
                Xref_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 16
                Xref_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 17 

                VCDomainsCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 18 
                VCDomainsOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 19 

                NegativeResponseName = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, variantReader);
                UnkByte = CaesarReader.ReadBitflagInt8(ref bitFlags, variantReader);  // 20 byte

                // vcdomain
                VCDomainPoolOffsets = new List<int>();
                variantReader.BaseStream.Seek(VCDomainsOffset, SeekOrigin.Begin);
                for (int variantCodingIndex = 0; variantCodingIndex < VCDomainsCount; variantCodingIndex++)
                {
                    VCDomainPoolOffsets.Add(variantReader.ReadInt32());
                }
                // diagnostic services
                DiagServicesPoolOffsets = new List<int>();
                variantReader.BaseStream.Seek(DiagServicesOffset, SeekOrigin.Begin);
                for (int diagIndex = 0; diagIndex < DiagServicesCount; diagIndex++)
                {
                    DiagServicesPoolOffsets.Add(variantReader.ReadInt32());
                }
                // DTCs
                //DTCsPoolOffsets = new List<int>();
                DTCsPoolOffsetsWithBounds = new List<Tuple<int, int, int>>();
                variantReader.BaseStream.Seek(DTC_Offset, SeekOrigin.Begin);
                for (int dtcIndex = 0; dtcIndex < DTC_Count; dtcIndex++)
                {
                    int actualIndex = variantReader.ReadInt32();
                    int xrefStart = variantReader.ReadInt32(); 
                    int xrefCount = variantReader.ReadInt32(); // stitch with table H : int __cdecl DIECUGetNumberOfEnvForAllErrors(DI_ECUINFO *ecuh, int a2, int a3)
                    //DTCsPoolOffsets.Add(actualIndex); // todo: depreciate this
                    DTCsPoolOffsetsWithBounds.Add(new Tuple<int, int, int>(actualIndex, xrefStart, xrefCount));
                }
                // EnvCtxs
                EnvironmentContextsPoolOffsets = new List<int>();
                variantReader.BaseStream.Seek(EnvironmentCtx_Offset, SeekOrigin.Begin);
                for (int envIndex = 0; envIndex < EnvironmentCtx_Count; envIndex++)
                {
                    EnvironmentContextsPoolOffsets.Add(variantReader.ReadInt32());
                }
            }

            CreateVCDomains(parentEcu, language);
            CreateDiagServices(parentEcu, language);
            CreateVariantPatterns(reader);
            CreateComParameters(reader, parentEcu);
            CreateDTCs(parentEcu, language);
            CreateEnvironmentContexts(parentEcu, language);
            CreateXrefs(reader, parentEcu, language);
            //PrintDebug();
        }

        // this function is parked here since the values are drawn from EnvironmentContexts // Xref_Count and Xref_Offset;
        public List<DiagService> GetEnvironmentContextsForDTC(DTC inDtc)
        {
            List<DiagService> ctxList = new List<DiagService>();

            for (int i = inDtc.XrefStart; i < (inDtc.XrefStart + inDtc.XrefCount); i++) 
            {
                foreach (DiagService envToTest in EnvironmentContexts) 
                {
                    int xref = Xrefs[i];
                    if (envToTest.PoolIndex == xref)
                    {
                        ctxList.Add(envToTest);
                        break;
                    }
                }
            }
            return ctxList;
        }

        public void CreateComParameters(BinaryReader reader, ECU parentEcu)
        {
            // this is unusual as it doesn't use the usual caesar-style bitflag reads
            // for reasons unknown the comparam is attached to the basevariant
            long comparamBaseAddress = BaseAddress + ComParamsOffset;
            // Console.WriteLine($"Comparam base: 0x{comparamBaseAddress:X} : number of comparams: {ComParamsCount} ");
            reader.BaseStream.Seek(comparamBaseAddress, SeekOrigin.Begin);
            List<long> comparameterOffsets = new List<long>();
            for (int comIndex = 0; comIndex < ComParamsCount; comIndex++)
            {
                comparameterOffsets.Add(reader.ReadInt32() + comparamBaseAddress);
            }

            if (parentEcu.ECUInterfaces.Count == 0)
            {
                throw new Exception("Invalid communication parameter : no parent interface");
            }

            foreach (long comparamOffset in comparameterOffsets)
            {
                ComParameter param = new ComParameter(reader, comparamOffset, parentEcu.ECUInterfaces, Language);

                // KW2C3PE uses a different parent addressing style
                int parentIndex = param.ParentInterfaceIndex > 0 ? param.ParentInterfaceIndex : param.SubinterfaceIndex;

                if (param.ParentInterfaceIndex >= parentEcu.ECUInterfaceSubtypes.Count)
                {
                    throw new Exception("ComParam: tried to assign to nonexistent interface");
                }
                else
                {
                    parentEcu.ECUInterfaceSubtypes[parentIndex].CommunicationParameters.Add(param);
                }
            }
        }

        public void CreateVariantPatterns(BinaryReader reader) 
        {
            long tableOffset = BaseAddress + MatchingPatternOffset;
            reader.BaseStream.Seek(tableOffset, SeekOrigin.Begin);

            VariantPatterns.Clear();
            for (int patternIndex = 0; patternIndex < MatchingPatternCount; patternIndex++) 
            {
                reader.BaseStream.Seek(tableOffset + (patternIndex * 4), SeekOrigin.Begin);
                int patternOffset = reader.ReadInt32();
                long patternAddress = patternOffset + tableOffset;

                ECUVariantPattern pattern = new ECUVariantPattern(reader, patternAddress);
                VariantPatterns.Add(pattern);
            }
        }

        public VCDomain GetVCDomainByName(string name)
        {
            foreach (VCDomain domain in VCDomains)
            {
                if (domain.Qualifier == name)
                {
                    return domain;
                }
            }
            return null;
        }
        public DiagService GetDiagServiceByName(string name)
        {
            foreach (DiagService diag in DiagServices)
            {
                if (diag.Qualifier == name)
                {
                    return diag;
                }
            }
            return null;
        }
        public string[] GetVCDomainNames()
        {
            List<string> result = new List<string>();
            foreach (VCDomain domain in VCDomains)
            {
                result.Add(domain.Qualifier);
            }
            return result.ToArray();
        }

        private void CreateVCDomains(ECU parentEcu, CTFLanguage language)
        {
            VCDomains = new List<VCDomain>();
            foreach (int variantCodingDomainEntry in VCDomainPoolOffsets)
            {
                /*
                VCDomain vcDomain = new VCDomain(reader, parentEcu, language, variantCodingDomainEntry);
                VCDomains.Add(vcDomain);
                */
                VCDomains.Add(ParentECU.GlobalVCDs[variantCodingDomainEntry]);
            }
        }
        private void CreateDiagServices(ECU parentEcu, CTFLanguage language)
        {
            // unlike variant domains, storing references to the parent objects in the ecu is preferable since this is relatively larger
            //DiagServices = new List<DiagService>();

            DiagServices = new DiagService[DiagServicesPoolOffsets.Count];

            /*
            // computationally expensive, 40ish % runtime is spent here
            // easier to read, below optimization essentially accomplishes this in a shorter period

            foreach (DiagService diagSvc in parentEcu.GlobalDiagServices)
            {
                for (int i = 0; i < DiagServicesPoolOffsets.Count; i++)
                {
                    if (diagSvc.PoolIndex == DiagServicesPoolOffsets[i])
                    {
                        DiagServices[i] = diagSvc;
                    }
                }
            }
            */
            // optimization hack
            int poolSize = DiagServicesPoolOffsets.Count;
            for (int i = 0; i < poolSize; i++) 
            {
                if (i == DiagServicesPoolOffsets[i])
                {
                    DiagServices[i] = parentEcu.GlobalDiagServices[i];
                }
            }
            DiagServicesPoolOffsets.Sort();
            int lowestIndex = 0;
            int loopMax = parentEcu.GlobalDiagServices.Count;
            for (int i = 0; i < poolSize; i++)
            {
                if (DiagServices[i] != null) 
                {
                    continue;
                }
                for (int globalIndex = lowestIndex; globalIndex < loopMax; globalIndex++)
                {
                    if (parentEcu.GlobalDiagServices[globalIndex].PoolIndex == DiagServicesPoolOffsets[i])
                    {
                        DiagServices[i] = parentEcu.GlobalDiagServices[globalIndex];
                        lowestIndex = globalIndex;
                        break;
                    }
                }
            }
        }
        private void CreateDTCs(ECU parentEcu, CTFLanguage language)
        {
            int dtcPoolSize = DTCsPoolOffsetsWithBounds.Count;
            DTCs = new DTC[dtcPoolSize];

            for (int i = 0; i < dtcPoolSize; i++) 
            {
                if (i == DTCsPoolOffsetsWithBounds[i].Item1) 
                {
                    DTCs[i] = parentEcu.GlobalDTCs[i];
                    DTCs[i].XrefStart = DTCsPoolOffsetsWithBounds[i].Item2;
                    DTCs[i].XrefCount = DTCsPoolOffsetsWithBounds[i].Item3;
                }
            }
            DTCsPoolOffsetsWithBounds.Sort((x, y) => x.Item1.CompareTo(y.Item1));
            int lowestIndex = 0;
            int loopMax = ParentECU.GlobalDTCs.Count;
            for (int i = 0; i < dtcPoolSize; i++) 
            {
                if (DTCs[i] != null)
                {
                    continue;
                }
                for (int globalIndex = lowestIndex; globalIndex < loopMax; globalIndex++)
                {
                    if (ParentECU.GlobalDTCs[globalIndex].PoolIndex == DTCsPoolOffsetsWithBounds[i].Item1) 
                    {
                        DTCs[i] = parentEcu.GlobalDTCs[globalIndex];
                        DTCs[i].XrefStart = DTCsPoolOffsetsWithBounds[i].Item2;
                        DTCs[i].XrefCount = DTCsPoolOffsetsWithBounds[i].Item3;
                        lowestIndex = globalIndex;
                        break;
                    }
                }
            }

            /*
            // same thing as above, just more readable and slower
            foreach (DTC dtc in parentEcu.GlobalDTCs)
            {
                for (int i = 0; i < DTCsPoolOffsetsWithBounds.Count; i++)
                {
                    if (dtc.PoolIndex == DTCsPoolOffsetsWithBounds[i].Item1)
                    {
                        // this is only valid on the assumption that DTC instances are unique (e.g. not shared from a base variant)
                        dtc.XrefStart = DTCsPoolOffsetsWithBounds[i].Item2;
                        dtc.XrefCount = DTCsPoolOffsetsWithBounds[i].Item3;
                        DTCs[i] = dtc;
                    }
                }
            }
            */
        }
        private void CreateXrefs(BinaryReader reader, ECU parentEcu, CTFLanguage language)
        {
            Xrefs = new int[Xref_Count];
            reader.BaseStream.Seek(BaseAddress + Xref_Offset, SeekOrigin.Begin);
            for (int i = 0; i < Xref_Count; i++)
            {
                Xrefs[i] = reader.ReadInt32();
            }
        }
        private void CreateEnvironmentContexts(ECU parentEcu, CTFLanguage language)
        {
            int envPoolSize = EnvironmentContextsPoolOffsets.Count;
            EnvironmentContexts = new DiagService[envPoolSize];

            for (int i = 0; i < envPoolSize; i++)
            {
                if (i == EnvironmentContextsPoolOffsets[i])
                {
                    EnvironmentContexts[i] = parentEcu.GlobalEnvironmentContexts[i];
                }
            }
            EnvironmentContextsPoolOffsets.Sort();
            int lowestIndex = 0;
            int loopMax = parentEcu.GlobalEnvironmentContexts.Count;
            for (int i = 0; i < envPoolSize; i++)
            {
                if (EnvironmentContexts[i] != null)
                {
                    continue;
                }
                for (int globalIndex = lowestIndex; globalIndex < loopMax; globalIndex++)
                {
                    if (parentEcu.GlobalEnvironmentContexts[globalIndex].PoolIndex == EnvironmentContextsPoolOffsets[i])
                    {
                        EnvironmentContexts[i] = parentEcu.GlobalEnvironmentContexts[globalIndex];
                        lowestIndex = globalIndex;
                        break;
                    }
                }
            }
            /*
            // same thing, more readable, much slower
  
Download .txt
gitextract_yphdzm_6/

├── .gitignore
├── Caesar/
│   ├── Caesar/
│   │   ├── App.config
│   │   ├── BitUtility.cs
│   │   ├── CFFHeader.cs
│   │   ├── CTFHeader.cs
│   │   ├── CTFLanguage.cs
│   │   ├── Caesar.csproj
│   │   ├── CaesarContainer.cs
│   │   ├── CaesarReader.cs
│   │   ├── CaesarStructure.cs
│   │   ├── ComParameter.cs
│   │   ├── DSCContext.cs
│   │   ├── DTC.cs
│   │   ├── DiagPreparation.cs
│   │   ├── DiagPresentation.cs
│   │   ├── DiagService.cs
│   │   ├── ECU.cs
│   │   ├── ECUInterface.cs
│   │   ├── ECUInterfaceSubtype.cs
│   │   ├── ECUVariant.cs
│   │   ├── ECUVariantPattern.cs
│   │   ├── Flash/
│   │   │   ├── CaesarFlashContainer.cs
│   │   │   ├── FlashDataBlock.cs
│   │   │   ├── FlashDescriptionHeader.cs
│   │   │   ├── FlashHeader.cs
│   │   │   ├── FlashSecurity.cs
│   │   │   └── FlashSegment.cs
│   │   ├── Program.cs
│   │   ├── Properties/
│   │   │   └── AssemblyInfo.cs
│   │   ├── Scale.cs
│   │   ├── StubHeader.cs
│   │   ├── VCDomain.cs
│   │   ├── VCFragment.cs
│   │   ├── VCSubfragment.cs
│   │   └── packages.config
│   ├── Caesar.sln
│   ├── Diogenes/
│   │   ├── App.config
│   │   ├── DiagnosticProtocol/
│   │   │   ├── BaseProtocol.cs
│   │   │   ├── KW2C3PE.cs
│   │   │   ├── UDS.cs
│   │   │   └── UnsupportedProtocol.cs
│   │   ├── Diogenes.csproj
│   │   ├── ECUConnection.cs
│   │   ├── ECUFlashMetadata.cs
│   │   ├── ECUIdentification.cs
│   │   ├── ECUMetadata.cs
│   │   ├── Forms/
│   │   │   ├── AboutForm.Designer.cs
│   │   │   ├── AboutForm.cs
│   │   │   ├── AboutForm.resx
│   │   │   ├── BlockDownload.Designer.cs
│   │   │   ├── BlockDownload.cs
│   │   │   ├── BlockDownload.resx
│   │   │   ├── DTCForm.Designer.cs
│   │   │   ├── DTCForm.cs
│   │   │   ├── DTCForm.resx
│   │   │   ├── FlashSplicer.Designer.cs
│   │   │   ├── FlashSplicer.cs
│   │   │   ├── FlashSplicer.resx
│   │   │   ├── GenericLoader.Designer.cs
│   │   │   ├── GenericLoader.cs
│   │   │   ├── GenericLoader.resx
│   │   │   ├── GenericPicker.Designer.cs
│   │   │   ├── GenericPicker.cs
│   │   │   ├── GenericPicker.resx
│   │   │   ├── MainForm.Designer.cs
│   │   │   ├── MainForm.cs
│   │   │   ├── MainForm.resx
│   │   │   ├── PickDiagForm.Designer.cs
│   │   │   ├── PickDiagForm.cs
│   │   │   ├── PickDiagForm.resx
│   │   │   ├── RunDiagForm.Designer.cs
│   │   │   ├── RunDiagForm.cs
│   │   │   ├── RunDiagForm.resx
│   │   │   ├── SecurityLevelForm.Designer.cs
│   │   │   ├── SecurityLevelForm.cs
│   │   │   ├── SecurityLevelForm.resx
│   │   │   ├── TraceForm.Designer.cs
│   │   │   ├── TraceForm.cs
│   │   │   ├── TraceForm.resx
│   │   │   ├── UDSHexEditor.Designer.cs
│   │   │   ├── UDSHexEditor.cs
│   │   │   ├── UDSHexEditor.resx
│   │   │   ├── VCForm.Designer.cs
│   │   │   ├── VCForm.cs
│   │   │   └── VCForm.resx
│   │   ├── Preferences.cs
│   │   ├── Program.cs
│   │   ├── Properties/
│   │   │   ├── AssemblyInfo.cs
│   │   │   ├── Resources.Designer.cs
│   │   │   ├── Resources.resx
│   │   │   ├── Settings.Designer.cs
│   │   │   └── Settings.settings
│   │   ├── Reports/
│   │   │   ├── DTCReport.cs
│   │   │   └── VCReport.cs
│   │   ├── SecurityAccess/
│   │   │   ├── DllContext.cs
│   │   │   ├── ExportDefinition.cs
│   │   │   └── SecurityAutoLogin.cs
│   │   ├── Simulation/
│   │   │   ├── SimulatedDevice.cs
│   │   │   └── Simulated_CRD3.cs
│   │   ├── TextboxWriter.cs
│   │   ├── UnmanagedUtility.cs
│   │   ├── VariantCoding.cs
│   │   └── packages.config
│   └── Trafo/
│       ├── App.config
│       ├── Program.cs
│       ├── Properties/
│       │   └── AssemblyInfo.cs
│       ├── Trafo.csproj
│       └── packages.config
├── LICENSE
└── README.md
Download .txt
SYMBOL INDEX (634 symbols across 79 files)

FILE: Caesar/Caesar/BitUtility.cs
  class BitUtility (line 11) | public class BitUtility
    method Memset (line 18) | public static void Memset(byte value, byte[] buf)
    method StringToByteArrayFastest (line 26) | private static byte[] StringToByteArrayFastest(string hex)
    method GetHexValue (line 41) | private static int GetHexValue(char hex)
    method BytesToHex (line 52) | public static string BytesToHex(byte[] inBytes, bool spacedOut = false)
    method BytesFromHex (line 62) | public static byte[] BytesFromHex(string hexString)
    method PadBytes (line 73) | public static byte[] PadBytes(byte[] inData, int finalSize)
    type UIntFloat (line 84) | [StructLayout(LayoutKind.Explicit)]
    method ToFloat (line 99) | public static float ToFloat(uint value)
    method BitArrayToByteArray (line 109) | public static byte[] BitArrayToByteArray(byte[] inArray, bool littleEn...
    method ByteArrayToBitArray (line 140) | public static byte[] ByteArrayToBitArray(byte[] inArray, bool littleEn...
    method BytesToBitString (line 168) | public static string BytesToBitString(byte[] inArray)
    method BytesToDecimalString (line 177) | public static string BytesToDecimalString(byte[] inArray)
    method BytesFromDecimalString (line 186) | public static byte[] BytesFromDecimalString(string inData)
    method BitsToString (line 197) | public static string BitsToString(byte[] inArray)
    method BitRoundtripTest (line 211) | public void BitRoundtripTest()
    method CheckHexValid (line 243) | public static bool CheckHexValid(string inHex)

FILE: Caesar/Caesar/CFFHeader.cs
  class CFFHeader (line 10) | public class CFFHeader
    method CFFHeader (line 38) | public CFFHeader()
    method CFFHeader (line 41) | public CFFHeader(BinaryReader reader)
    method PrintDebug (line 75) | public void PrintDebug()

FILE: Caesar/Caesar/CTFHeader.cs
  class CTFHeader (line 10) | public class CTFHeader
    method CTFHeader (line 24) | public CTFHeader() { }
    method CTFHeader (line 25) | public CTFHeader(BinaryReader reader, long baseAddress, int headerSize)
    method PrintDebug (line 53) | public void PrintDebug()

FILE: Caesar/Caesar/CTFLanguage.cs
  class CTFLanguage (line 10) | public class CTFLanguage
    method CTFLanguage (line 20) | public CTFLanguage() { }
    method CTFLanguage (line 21) | public CTFLanguage(BinaryReader reader, long baseAddress, int headerSize)
    method LoadStrings (line 36) | public void LoadStrings(BinaryReader reader, int headerSize, Encoding ...
    method GetString (line 50) | public string GetString(int stringId)
    method GetString (line 55) | public static string GetString(List<string> language, int stringId)
    method PrintDebug (line 68) | public void PrintDebug()

FILE: Caesar/Caesar/CaesarContainer.cs
  class CaesarContainer (line 13) | public class CaesarContainer
    method CaesarContainer (line 23) | public CaesarContainer() { }
    method CaesarContainer (line 27) | public CaesarContainer(byte[] fileBytes)
    method SerializeContainer (line 58) | public static string SerializeContainer(CaesarContainer container)
    method DeserializeContainer (line 63) | public static CaesarContainer DeserializeContainer(string json)
    method DeserializeCompressedContainer (line 76) | public static CaesarContainer DeserializeCompressedContainer(byte[] co...
    method SerializeCompressedContainer (line 81) | public static byte[] SerializeCompressedContainer(CaesarContainer cont...
    method Inflate (line 87) | private static byte[] Inflate(byte[] input)
    method Deflate (line 101) | private static byte[] Deflate(byte[] input)
    method VerifyChecksum (line 113) | public static bool VerifyChecksum(byte[] fileBytes, out uint checksum)
    method GetCaesarVersionString (line 126) | public static string GetCaesarVersionString()
    method ReadFileChecksum (line 133) | public static uint ReadFileChecksum(byte[] fileBytes)
    method GetECUVariantByName (line 138) | public ECUVariant GetECUVariantByName(string name)
    method GetECUByName (line 152) | public ECU GetECUByName(string name)
    method GetECUVariantNames (line 164) | public string[] GetECUVariantNames()
    method GetLanguage (line 178) | public CTFLanguage GetLanguage()
    method ReadECU (line 192) | void ReadECU(BinaryReader fileReader)
    method ReadCTF (line 208) | void ReadCTF(BinaryReader fileReader)
    method ReadCFFDefinition (line 221) | void ReadCFFDefinition(BinaryReader fileReader)
    method GetFileSize (line 249) | public string GetFileSize()
    method BytesToString (line 254) | private static string BytesToString(long byteCount)
    method Equals (line 267) | public override bool Equals(object obj)
    method GetHashCode (line 278) | public override int GetHashCode()

FILE: Caesar/Caesar/CaesarReader.cs
  class CaesarReader (line 10) | public class CaesarReader
    method ReadBitflagStringWithReader (line 15) | public static string ReadBitflagStringWithReader(ref ulong bitFlags, B...
    method ReadBitflagDumpWithReader (line 36) | public static byte[] ReadBitflagDumpWithReader(ref ulong bitFlags, Bin...
    method ReadBitflagDumpWithReaderAsString (line 57) | public static string ReadBitflagDumpWithReaderAsString(ref ulong bitFl...
    method ReadStringFromBinaryReader (line 63) | public static string ReadStringFromBinaryReader(BinaryReader reader, E...
    method CheckAndAdvanceBitflag (line 104) | public static bool CheckAndAdvanceBitflag(ref ulong bitFlag)
    method ReadBitflagRawBytes (line 111) | public static byte[] ReadBitflagRawBytes(ref ulong bitFlags, BinaryRea...
    method ReadBitflagFloat (line 117) | public static float ReadBitflagFloat(ref ulong bitFlags, BinaryReader ...
    method ReadBitflagInt32 (line 126) | public static int ReadBitflagInt32(ref ulong bitFlags, BinaryReader re...
    method ReadBitflagUInt32 (line 134) | public static uint ReadBitflagUInt32(ref ulong bitFlags, BinaryReader ...
    method ReadBitflagInt16 (line 142) | public static short ReadBitflagInt16(ref ulong bitFlags, BinaryReader ...
    method ReadBitflagUInt16 (line 150) | public static ushort ReadBitflagUInt16(ref ulong bitFlags, BinaryReade...
    method ReadBitflagInt8 (line 158) | public static int ReadBitflagInt8(ref ulong bitFlags, BinaryReader rea...
    method ReadBitflagUInt8 (line 166) | public static byte ReadBitflagUInt8(ref ulong bitFlags, BinaryReader r...
    method ReadIntWithSize (line 175) | public static int ReadIntWithSize(BinaryReader reader, int size, long ...
    method ReadUIntWithSize (line 195) | public static uint ReadUIntWithSize(BinaryReader reader, int size, lon...
    method CrcAccumulate (line 251) | public static UInt32 CrcAccumulate(byte[] inputBuffer, uint currentChe...
    method ComputeFileChecksum (line 267) | public static uint ComputeFileChecksum(byte[] fileBytes)
    method ComputeFileChecksumLazy (line 286) | public static uint ComputeFileChecksumLazy(byte[] fileBytes)

FILE: Caesar/Caesar/CaesarStructure.cs
  class CaesarStructure (line 10) | class CaesarStructure
    type StructureName (line 13) | public enum StructureName
    method GetOffset (line 98) | public static void GetOffset(StructureName name, int memberIndex)
    method GetCaesarLayout (line 103) | public static byte[] GetCaesarLayout(StructureName name)
    method FillCaesarTypes (line 109) | public static void FillCaesarTypes()
    method ReadCBFWithOffset (line 157) | public static int ReadCBFWithOffset(int memberIndex, StructureName str...
    method ReadCBFWithOffsetUnsigned (line 166) | public static uint ReadCBFWithOffsetUnsigned(int memberIndex, Structur...
    method GetCBFOffset (line 176) | public static int GetCBFOffset(int memberIndex, StructureName structur...

FILE: Caesar/Caesar/ComParameter.cs
  class ComParameter (line 10) | public class ComParameter
    method Restore (line 28) | public void Restore(CTFLanguage language)
    method ComParameter (line 33) | public ComParameter() { }
    method ComParameter (line 36) | public ComParameter(BinaryReader reader, long baseAddress, List<ECUInt...
    method PrintDebug (line 71) | public void PrintDebug()

FILE: Caesar/Caesar/DSCContext.cs
  class DSCContext (line 11) | public class DSCContext
    method DSCContext (line 13) | public DSCContext(byte[] dscContainerBytes)
    type DSCBasicType (line 145) | public enum DSCBasicType
    type DSCDerivedType (line 157) | public enum DSCDerivedType
    method GetDscTypeSize (line 165) | public static int GetDscTypeSize(int basicType, int derivedType)

FILE: Caesar/Caesar/DTC.cs
  class DTC (line 10) | public class DTC
    type DTCStatusByte (line 12) | public enum DTCStatusByte : uint
    method Restore (line 44) | public void Restore(CTFLanguage language, ECU parentEcu)
    method DTC (line 50) | public DTC() { }
    method DTC (line 52) | public DTC(BinaryReader reader, CTFLanguage language, long baseAddress...
    method FindDTCById (line 79) | public static DTC FindDTCById(string id, ECUVariant variant)
    method PrintDebug (line 90) | public void PrintDebug()

FILE: Caesar/Caesar/DiagPreparation.cs
  class DiagPreparation (line 10) | public class DiagPreparation
    type InferredDataType (line 41) | public enum InferredDataType
    method Restore (line 54) | public void Restore(CTFLanguage language, ECU parentEcu, DiagService p...
    method DiagPreparation (line 61) | public DiagPreparation() { }
    method DiagPreparation (line 66) | public DiagPreparation(BinaryReader reader, CTFLanguage language, long...
    method GetSizeInBits (line 104) | public int GetSizeInBits(BinaryReader reader, bool verbose = true)
    method PrintDebug (line 358) | public void PrintDebug()

FILE: Caesar/Caesar/DiagPresentation.cs
  class DiagPresentation (line 10) | public class DiagPresentation
    method Restore (line 72) | public void Restore(CTFLanguage language)
    method DiagPresentation (line 81) | public DiagPresentation() { }
    method DiagPresentation (line 85) | public DiagPresentation(BinaryReader reader, long baseAddress, int pre...
    method InterpretData (line 160) | public string InterpretData(byte[] inBytes, DiagPreparation inPreparat...
    method GetDataType (line 339) | public int GetDataType()
    method PrintDebug (line 414) | public void PrintDebug()
    method CopyMinDebug (line 484) | public string CopyMinDebug()

FILE: Caesar/Caesar/DiagService.cs
  class DiagService (line 12) | public class DiagService
    type ServiceType (line 27) | public enum ServiceType
    method Restore (line 114) | public void Restore(CTFLanguage language, ECU parentEcu)
    method DiagService (line 138) | public DiagService() { }
    method DiagService (line 140) | public DiagService(BinaryReader reader, CTFLanguage language, long bas...
    method GetDescription (line 346) | public string GetDescription()
    method GetName (line 350) | public string GetName()
    method GetCALInt16Offset (line 355) | public long GetCALInt16Offset(BinaryReader reader)
    method PrintDebug (line 378) | public void PrintDebug()

FILE: Caesar/Caesar/ECU.cs
  class ECU (line 10) | public class ECU
    method Restore (line 105) | public void Restore(CTFLanguage language, CaesarContainer parentContai...
    method ReadDiagjobPool (line 147) | public byte[] ReadDiagjobPool(BinaryReader reader)
    method ReadVariantPool (line 156) | public byte[] ReadVariantPool(BinaryReader reader)
    method ReadVarcodingPool (line 165) | public byte[] ReadVarcodingPool(BinaryReader reader)
    method ReadECUInfoPool (line 174) | public byte[] ReadECUInfoPool(BinaryReader reader)
    method ReadECUPresentationsPool (line 182) | public byte[] ReadECUPresentationsPool(BinaryReader reader)
    method ReadECUInternalPresentationsPool (line 190) | public byte[] ReadECUInternalPresentationsPool(BinaryReader reader)
    method ReadECUEnvPool (line 198) | public byte[] ReadECUEnvPool(BinaryReader reader)
    method ReadECUUnkPool (line 206) | public byte[] ReadECUUnkPool (BinaryReader reader)
    method ReadECUDtcPool (line 215) | public byte[] ReadECUDtcPool(BinaryReader reader)
    method ReadEcuPool (line 224) | public byte[] ReadEcuPool(BinaryReader reader, long addressToReadFrom,...
    method ECU (line 230) | public ECU() { }
    method ECU (line 232) | public ECU(BinaryReader reader, CTFLanguage language, CFFHeader header...
    method CreateDiagServices (line 371) | public void CreateDiagServices(BinaryReader reader, CTFLanguage language)
    method CreateDTCs (line 397) | public void CreateDTCs(BinaryReader reader, CTFLanguage language)
    method CreateVCDomains (line 417) | public void CreateVCDomains(BinaryReader reader, CTFLanguage language)
    method CreateEnvironments (line 436) | public void CreateEnvironments(BinaryReader reader, CTFLanguage language)
    method CreateUnk (line 473) | public void CreateUnk(BinaryReader reader, CTFLanguage language)
    method CreatePresentations (line 483) | public void CreatePresentations(BinaryReader reader, CTFLanguage langu...
    method CreateInternalPresentations (line 508) | public void CreateInternalPresentations(BinaryReader reader, CTFLangua...
    method CreateEcuVariants (line 527) | public void CreateEcuVariants(BinaryReader reader, CTFLanguage language)
    method PrintDebug (line 559) | public void PrintDebug()

FILE: Caesar/Caesar/ECUInterface.cs
  class ECUInterface (line 10) | public class ECUInterface
    method Restore (line 27) | public void Restore(CTFLanguage language)
    method ECUInterface (line 32) | public ECUInterface() { }
    method ECUInterface (line 34) | public ECUInterface(BinaryReader reader, long baseAddress)
    method PrintDebug (line 67) | public void PrintDebug()

FILE: Caesar/Caesar/ECUInterfaceSubtype.cs
  class ECUInterfaceSubtype (line 11) | public class ECUInterfaceSubtype
    type ParamName (line 13) | public enum ParamName
    method Restore (line 68) | public void Restore(CTFLanguage language)
    method ECUInterfaceSubtype (line 77) | public ECUInterfaceSubtype() { }
    method ECUInterfaceSubtype (line 79) | public ECUInterfaceSubtype(BinaryReader reader, long baseAddress, int ...
    method GetComParameterByName (line 104) | public ComParameter GetComParameterByName(string paramName)
    method GetComParameterValue (line 108) | public int GetComParameterValue(ParamName name)
    method GetComParameterValue (line 112) | public bool GetComParameterValue(ParamName name, out int result)
    method PrintDebug (line 127) | public void PrintDebug()

FILE: Caesar/Caesar/ECUVariant.cs
  class ECUVariant (line 10) | public class ECUVariant
    method Restore (line 67) | public void Restore(CTFLanguage language, ECU parentEcu)
    method ECUVariant (line 87) | public ECUVariant() { }
    method ECUVariant (line 89) | public ECUVariant(BinaryReader reader, ECU parentEcu, CTFLanguage lang...
    method GetEnvironmentContextsForDTC (line 180) | public List<DiagService> GetEnvironmentContextsForDTC(DTC inDtc)
    method CreateComParameters (line 199) | public void CreateComParameters(BinaryReader reader, ECU parentEcu)
    method CreateVariantPatterns (line 235) | public void CreateVariantPatterns(BinaryReader reader)
    method GetVCDomainByName (line 252) | public VCDomain GetVCDomainByName(string name)
    method GetDiagServiceByName (line 263) | public DiagService GetDiagServiceByName(string name)
    method GetVCDomainNames (line 274) | public string[] GetVCDomainNames()
    method CreateVCDomains (line 284) | private void CreateVCDomains(ECU parentEcu, CTFLanguage language)
    method CreateDiagServices (line 296) | private void CreateDiagServices(ECU parentEcu, CTFLanguage language)
    method CreateDTCs (line 347) | private void CreateDTCs(ECU parentEcu, CTFLanguage language)
    method CreateXrefs (line 400) | private void CreateXrefs(BinaryReader reader, ECU parentEcu, CTFLangua...
    method CreateEnvironmentContexts (line 409) | private void CreateEnvironmentContexts(ECU parentEcu, CTFLanguage lang...
    method PrintDebug (line 455) | public void PrintDebug()

FILE: Caesar/Caesar/ECUVariantPattern.cs
  class ECUVariantPattern (line 11) | public class ECUVariantPattern
    method Restore (line 51) | public void Restore()
    method ECUVariantPattern (line 56) | public ECUVariantPattern() { }
    method ECUVariantPattern (line 58) | public ECUVariantPattern(BinaryReader reader, long baseAddress)
    method PrintDebug (line 102) | public void PrintDebug()

FILE: Caesar/Caesar/Flash/CaesarFlashContainer.cs
  class CaesarFlashContainer (line 10) | public class CaesarFlashContainer
    method CaesarFlashContainer (line 16) | public CaesarFlashContainer(byte[] fileBytes)
    method ReadCTF (line 38) | void ReadCTF(BinaryReader fileReader)
    method ReadFileChecksum (line 49) | public uint ReadFileChecksum(byte[] fileBytes)
    method ReadFlashCFF (line 54) | void ReadFlashCFF(BinaryReader fileReader)
    method ExportCFFMemorySegments (line 59) | public static void ExportCFFMemorySegments(string filePath)
    method SpliceCFFFile (line 122) | public void SpliceCFFFile(string filePath)

FILE: Caesar/Caesar/Flash/FlashDataBlock.cs
  class FlashDataBlock (line 10) | public class FlashDataBlock
    method FlashDataBlock (line 43) | public FlashDataBlock(BinaryReader reader, long baseAddress)
    method GetBlockLengthOffset (line 109) | public long GetBlockLengthOffset(BinaryReader reader)
    method GetFlashDataOffset (line 130) | public long GetFlashDataOffset(BinaryReader reader)
    method PrintDebug (line 151) | public void PrintDebug()

FILE: Caesar/Caesar/Flash/FlashDescriptionHeader.cs
  class FlashDescriptionHeader (line 12) | public class FlashDescriptionHeader
    method FlashDescriptionHeader (line 28) | public FlashDescriptionHeader(BinaryReader reader, long baseAddress)
    method PrintDebug (line 49) | public void PrintDebug()

FILE: Caesar/Caesar/Flash/FlashHeader.cs
  class FlashHeader (line 10) | public class FlashHeader
    method FlashHeader (line 44) | public FlashHeader(BinaryReader reader)
    method PrintDebug (line 100) | public void PrintDebug()

FILE: Caesar/Caesar/Flash/FlashSecurity.cs
  class FlashSecurity (line 10) | public class FlashSecurity
    method FlashSecurity (line 30) | public FlashSecurity(BinaryReader reader, long baseAddress)
    method PrintDebug (line 54) | public void PrintDebug()

FILE: Caesar/Caesar/Flash/FlashSegment.cs
  class FlashSegment (line 10) | public class FlashSegment
    method FlashSegment (line 27) | public FlashSegment(BinaryReader reader, long baseAddress)
    method GetMappedAddressFileOffset (line 46) | public long GetMappedAddressFileOffset(BinaryReader reader)
    method GetSegmentLengthFileOffset (line 61) | public long GetSegmentLengthFileOffset(BinaryReader reader)
    method PrintDebug (line 78) | public void PrintDebug()

FILE: Caesar/Caesar/Program.cs
  class Program (line 11) | class Program
    method Main (line 15) | static void Main(string[] args)
    method RunLibraryTest (line 23) | static void RunLibraryTest()
    method LoadFilePaths (line 38) | static void LoadFilePaths(string path, List<string> result)

FILE: Caesar/Caesar/Scale.cs
  class Scale (line 10) | public class Scale
    method Restore (line 36) | public void Restore(CTFLanguage language)
    method Scale (line 41) | public Scale() { }
    method Scale (line 43) | public Scale(BinaryReader reader, long baseAddress, CTFLanguage language)
    method PrintDebug (line 72) | public void PrintDebug()

FILE: Caesar/Caesar/StubHeader.cs
  class StubHeader (line 9) | class StubHeader
    method ReadHeader (line 14) | public static void ReadHeader(byte[] header)

FILE: Caesar/Caesar/VCDomain.cs
  class VCDomain (line 10) | public class VCDomain
    method Restore (line 34) | public void Restore(CTFLanguage language, ECU parentEcu)
    method VCDomain (line 43) | public VCDomain() { }
    method VCDomain (line 46) | public VCDomain(BinaryReader reader, CTFLanguage language, long baseAd...
    method ValidateFragmentCoverage (line 129) | private void ValidateFragmentCoverage()
    method PrintDebug (line 157) | public void PrintDebug()

FILE: Caesar/Caesar/VCFragment.cs
  class VCFragment (line 10) | public class VCFragment
    method Restore (line 46) | public void Restore(ECU parentEcu, VCDomain parentDomain, CTFLanguage ...
    method VCFragment (line 56) | public VCFragment() { }
    method VCFragment (line 58) | public VCFragment(BinaryReader reader, VCDomain parentDomain, long fra...
    method GetSubfragmentConfiguration (line 120) | public VCSubfragment GetSubfragmentConfiguration(byte[] variantCodingV...
    method SetSubfragmentConfiguration (line 135) | public byte[] SetSubfragmentConfiguration(byte[] variantCodingValue, s...
    method SetSubfragmentConfiguration (line 147) | public byte[] SetSubfragmentConfiguration(byte[] variantCodingValue, V...
    method FindFragmentSize (line 158) | private void FindFragmentSize(BinaryReader reader)
    method PrintDebug (line 243) | public void PrintDebug(bool verbose=false)

FILE: Caesar/Caesar/VCSubfragment.cs
  class VCSubfragment (line 10) | public class VCSubfragment
    method Restore (line 27) | public void Restore(CTFLanguage language)
    method VCSubfragment (line 32) | public VCSubfragment() { }
    method VCSubfragment (line 34) | public VCSubfragment(BinaryReader reader, VCFragment parentFragment, C...
    method PrintDebug (line 60) | private void PrintDebug(bool verbose = false)

FILE: Caesar/Diogenes/DiagnosticProtocol/BaseProtocol.cs
  class BaseProtocol (line 10) | public class BaseProtocol
    method ConnectionEstablishedHandler (line 12) | public virtual void ConnectionEstablishedHandler(ECUConnection connect...
    method ConnectionClosingHandler (line 16) | public virtual void ConnectionClosingHandler(ECUConnection connection)
    method SendTesterPresent (line 21) | public virtual void SendTesterPresent(ECUConnection connection)
    method IsResponseToTesterPresent (line 26) | public virtual bool IsResponseToTesterPresent(byte[] inBuffer)
    method GetProtocolName (line 31) | public virtual string GetProtocolName()
    method SupportsUnlocking (line 35) | public virtual bool SupportsUnlocking()
    method QueryECUMetadata (line 40) | public virtual ECUMetadata QueryECUMetadata(ECUConnection connection)
    method ReportDtcsByStatusMask (line 45) | public virtual List<DTCContext> ReportDtcsByStatusMask(ECUConnection c...
    method GetDtcSnapshot (line 50) | public virtual bool GetDtcSnapshot(DTC dtc, ECUConnection connection, ...
    method GetProtocol (line 56) | public static BaseProtocol GetProtocol(string profileName)

FILE: Caesar/Diogenes/DiagnosticProtocol/KW2C3PE.cs
  class KW2C3PE (line 10) | public class KW2C3PE : BaseProtocol
    method EnterDiagnosticSession (line 12) | private static bool EnterDiagnosticSession(ECUConnection connection)
    method ExitDiagnosticSession (line 25) | private static bool ExitDiagnosticSession(ECUConnection connection)
    method GetVariantID_1A86 (line 38) | private static bool GetVariantID_1A86(ECUConnection connection, out in...
    method GetVariantID_1A87 (line 54) | private static bool GetVariantID_1A87(ECUConnection connection, out in...
    method GetVariantID (line 71) | private static bool GetVariantID(ECUConnection connection, out int var...
    method ReportDtcsByStatusMask (line 87) | public override List<DTCContext> ReportDtcsByStatusMask(ECUConnection ...
    method GetDtcSnapshot (line 93) | public override bool GetDtcSnapshot(DTC dtc, ECUConnection connection,...
    method ConnectionEstablishedHandler (line 99) | public override void ConnectionEstablishedHandler(ECUConnection connec...
    method SendTesterPresent (line 118) | public override void SendTesterPresent(ECUConnection connection)
    method IsResponseToTesterPresent (line 124) | public override bool IsResponseToTesterPresent(byte[] inBuffer)
    method ConnectionClosingHandler (line 129) | public override void ConnectionClosingHandler(ECUConnection connection)
    method GetProtocolName (line 135) | public override string GetProtocolName()
    method SupportsUnlocking (line 140) | public override bool SupportsUnlocking()

FILE: Caesar/Diogenes/DiagnosticProtocol/UDS.cs
  class UDS (line 11) | public class UDS : BaseProtocol
    method GetNegativeResponseDescriptions (line 16) | private static string[] GetNegativeResponseDescriptions()
    method GetMessageDescriptions (line 83) | private static Dictionary<int, string> GetMessageDescriptions()
    method GetCommandDescription (line 119) | public static string GetCommandDescription(byte[] command)
    method IsNegativeResponse (line 152) | private static bool IsNegativeResponse(byte[] command)
    method EnterDiagnosticSession (line 157) | private static bool EnterDiagnosticSession(ECUConnection connection)
    method ExitDiagnosticSession (line 170) | private static bool ExitDiagnosticSession(ECUConnection connection)
    method GetVariantID (line 183) | private static bool GetVariantID(ECUConnection connection, out int var...
    method ReportDtcsByStatusMask (line 202) | public override List<DTCContext> ReportDtcsByStatusMask(ECUConnection ...
    method GetDtcSnapshot (line 251) | public override bool GetDtcSnapshot(DTC dtc, ECUConnection connection,...
    method QueryECUMetadata (line 272) | public override ECUMetadata QueryECUMetadata(ECUConnection connection)
    method ReadDataByIdentifier (line 356) | private static bool ReadDataByIdentifier(ECUConnection connection, ush...
    method ConnectionEstablishedHandler (line 374) | public override void ConnectionEstablishedHandler(ECUConnection connec...
    method SendTesterPresent (line 392) | public override void SendTesterPresent(ECUConnection connection)
    method IsResponseToTesterPresent (line 397) | public override bool IsResponseToTesterPresent(byte[] inBuffer)
    method ConnectionClosingHandler (line 402) | public override void ConnectionClosingHandler(ECUConnection connection)
    method GetProtocolName (line 407) | public override string GetProtocolName()
    method SupportsUnlocking (line 412) | public override bool SupportsUnlocking()

FILE: Caesar/Diogenes/DiagnosticProtocol/UnsupportedProtocol.cs
  class UnsupportedProtocol (line 9) | public class UnsupportedProtocol : BaseProtocol
    method ConnectionEstablishedHandler (line 11) | public override void ConnectionEstablishedHandler(ECUConnection connec...
    method GetProtocolName (line 16) | public override string GetProtocolName()
    method SupportsUnlocking (line 21) | public override bool SupportsUnlocking()

FILE: Caesar/Diogenes/ECUConnection.cs
  class ECUConnection (line 60) | public class ECUConnection
    type ConnectionState (line 95) | public enum ConnectionState
    type ConnectResponse (line 103) | public enum ConnectResponse
    method ECUConnection (line 111) | public ECUConnection()
    method ECUConnection (line 120) | public ECUConnection(string fileName, string friendlyName)
    method IsSimulation (line 154) | public bool IsSimulation()
    method GetAvailableJ2534NamesAndDrivers (line 159) | public static List<Tuple<string, string>> GetAvailableJ2534NamesAndDri...
    method TesterPresentTimer_Elapsed (line 172) | private void TesterPresentTimer_Elapsed(object sender, ElapsedEventArg...
    method OpenDevice (line 185) | public void OpenDevice()
    method ConnectionUpdateState (line 202) | private void ConnectionUpdateState()
    method SetConnectionDefaults (line 226) | public void SetConnectionDefaults()
    method Connect (line 233) | public ConnectResponse Connect(ECUInterfaceSubtype profile, ECU ecuCon...
    method DriverIsAVDI (line 315) | public bool DriverIsAVDI()
    method SetCANIdentifiers (line 322) | public void SetCANIdentifiers(ECUInterfaceSubtype profile)
    method SetCANIdentifiers (line 326) | public void SetCANIdentifiers(int canIdentifier, int rxCanIdentifier)
    method J2534SetFilters (line 336) | public void J2534SetFilters()
    method J2534SetConfig (line 353) | public void J2534SetConfig(ECUInterfaceSubtype profile)
    method J2534FlushBuffers (line 373) | public void J2534FlushBuffers()
    method SendDiagRequest (line 379) | public byte[] SendDiagRequest(DiagService diag)
    method ExecUserDiagJob (line 386) | public void ExecUserDiagJob(byte[] request, DiagService diagService)
    method SendMessage (line 407) | public byte[] SendMessage(IEnumerable<byte> message, bool testerPresen...
    method ReadResponse (line 470) | public byte[] ReadResponse(string originalMessageAsStringForDebug, boo...
    method IsECURequestingForWait (line 573) | public bool IsECURequestingForWait(byte[] response)
    method LogRead (line 590) | public void LogRead(IEnumerable<byte> inBuffer)
    method LogWrite (line 597) | public void LogWrite(IEnumerable<byte> inBuffer)
    method TryCleanup (line 605) | public void TryCleanup()

FILE: Caesar/Diogenes/ECUFlashMetadata.cs
  class ECUFlashMetadata (line 9) | public class ECUFlashMetadata

FILE: Caesar/Diogenes/ECUIdentification.cs
  class ECUIdentification (line 12) | public class ECUIdentification
    method TryReadChassisNumber (line 16) | public static bool TryReadChassisNumber(ECUConnection connection, out ...
    method TryReadUDSChassisNumber (line 77) | public static bool TryReadUDSChassisNumber(ECUConnection connection, o...
    method TryReadKW2C3PEChassisNumber (line 92) | public static bool TryReadKW2C3PEChassisNumber(ECUConnection connectio...
    method SetupConnectionForBaud (line 109) | public static void SetupConnectionForBaud(ECUConnection connection, in...

FILE: Caesar/Diogenes/ECUMetadata.cs
  class ECUMetadata (line 9) | public class ECUMetadata
    method GetHtmlTable (line 22) | public string GetHtmlTable(ECUConnection connection)
    method GetVendorName (line 72) | public static string GetVendorName(byte vendorId)
    method ShowMetadataModal (line 82) | public static void ShowMetadataModal(ECUConnection connection)
    type Vendor (line 119) | public enum Vendor : byte

FILE: Caesar/Diogenes/Forms/AboutForm.Designer.cs
  class AboutForm (line 4) | partial class AboutForm
    method Dispose (line 15) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 30) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/AboutForm.cs
  class AboutForm (line 13) | public partial class AboutForm : Form
    method AboutForm (line 15) | public AboutForm(string displayedVersion)
    method btnClose_Click (line 21) | private void btnClose_Click(object sender, EventArgs e)
    method linkLabel1_LinkClicked (line 26) | private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClicke...

FILE: Caesar/Diogenes/Forms/BlockDownload.Designer.cs
  class BlockDownload (line 4) | partial class BlockDownload
    method Dispose (line 15) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 30) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/BlockDownload.cs
  class BlockDownload (line 16) | public partial class BlockDownload : Form
    method BlockDownload (line 20) | public BlockDownload(ECUConnection connection)
    method BlockDownload_Load (line 26) | private void BlockDownload_Load(object sender, EventArgs e)
    method dgvMain_DragEnter (line 31) | private void dgvMain_DragEnter(object sender, DragEventArgs e)
    method dgvMain_DragDrop (line 39) | private void dgvMain_DragDrop(object sender, DragEventArgs e)
    method TryLoadBlock (line 50) | private void TryLoadBlock(string fileName)
    method PresentRows (line 78) | private void PresentRows()
    method btnDownload_Click (line 111) | private void btnDownload_Click(object sender, EventArgs e)
    method StartDownload (line 119) | private void StartDownload()
    method RaiseSTMin (line 247) | private void RaiseSTMin()
    method ResetSTMin (line 256) | private void ResetSTMin()
    method CreateDownloadRequest (line 265) | private byte[] CreateDownloadRequest(uint address, uint size)
    method GetAddressAndLengthFormatIdentifier (line 280) | private static byte GetAddressAndLengthFormatIdentifier(int addressSiz...
    method ValueToBEByteArrayConstrained (line 308) | private List<byte> ValueToBEByteArrayConstrained(long inValue, int size)
    method btnAddBlock_Click (line 320) | private void btnAddBlock_Click(object sender, EventArgs e)
    method btnRemoveBlocks_Click (line 334) | private void btnRemoveBlocks_Click(object sender, EventArgs e)
    method SetSessionStub (line 341) | private void SetSessionStub(ECUConnection Connection)
    method btnExportAsMono_Click (line 374) | private void btnExportAsMono_Click(object sender, EventArgs e)
  class FlashBlock (line 394) | public class FlashBlock

FILE: Caesar/Diogenes/Forms/DTCForm.Designer.cs
  class DTCForm (line 4) | partial class DTCForm
    method Dispose (line 15) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 30) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/DTCForm.cs
  class DTCForm (line 16) | public partial class DTCForm : Form
    method DTCForm (line 25) | public DTCForm(ECUConnection connection, ECUVariant variant)
    method DTCForm_Load (line 32) | private void DTCForm_Load(object sender, EventArgs e)
    method PresentDtcData (line 42) | private void PresentDtcData()
    method QueryDTC (line 52) | private void QueryDTC()
    method PresentDTCs (line 120) | private void PresentDTCs()
    method PresentEnvironmentContext (line 179) | private void PresentEnvironmentContext()
    method EnableDoubleBuffer (line 215) | public static void EnableDoubleBuffer(DataGridView dgv, bool setting)
    method clearAllDTCsToolStripMenuItem_Click (line 222) | private void clearAllDTCsToolStripMenuItem_Click(object sender, EventA...
    method clearSelectedDTCToolStripMenuItem_Click (line 230) | private void clearSelectedDTCToolStripMenuItem_Click(object sender, Ev...
    method ClearAllDTCs (line 243) | private void ClearAllDTCs()
    method ClearDTC (line 259) | private void ClearDTC(DTC dtc)
    method refreshDataToolStripMenuItem_Click (line 281) | private void refreshDataToolStripMenuItem_Click(object sender, EventAr...
    method dgvMain_SelectionChanged (line 287) | private void dgvMain_SelectionChanged(object sender, EventArgs e)
    method exportDTCsToolStripMenuItem_Click (line 292) | private void exportDTCsToolStripMenuItem_Click(object sender, EventArg...
    method viewAllAvailableDTCsToolStripMenuItem_Click (line 297) | private void viewAllAvailableDTCsToolStripMenuItem_Click(object sender...
  class DTCContext (line 310) | public class DTCContext

FILE: Caesar/Diogenes/Forms/FlashSplicer.Designer.cs
  class FlashSplicer (line 4) | partial class FlashSplicer
    method Dispose (line 15) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 30) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/FlashSplicer.cs
  class FlashSplicer (line 15) | public partial class FlashSplicer : Form
    method FlashSplicer (line 24) | public FlashSplicer()
    method openCFFFileToolStripMenuItem_Click (line 29) | private void openCFFFileToolStripMenuItem_Click(object sender, EventAr...
    method LoadCFF (line 42) | public void LoadCFF(string filePath)
    method GetLog (line 90) | private string GetLog()
    method PresentRows (line 134) | private void PresentRows()
    method GenericPicker_Load (line 199) | private void GenericPicker_Load(object sender, EventArgs e)
    method dgvMain_CellBeginEdit (line 204) | private void dgvMain_CellBeginEdit(object sender, DataGridViewCellCanc...
    method exportSplicedFileToolStripMenuItem_Click (line 229) | private void exportSplicedFileToolStripMenuItem_Click(object sender, E...
    method LoadMappedAddresses (line 351) | private bool LoadMappedAddresses()

FILE: Caesar/Diogenes/Forms/GenericLoader.Designer.cs
  class GenericLoader (line 4) | partial class GenericLoader
    method Dispose (line 15) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 30) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/GenericLoader.cs
  class GenericLoader (line 13) | public partial class GenericLoader : Form
    method GenericLoader (line 15) | public GenericLoader()
    method SetProgressValue (line 19) | public void SetProgressValue(int value)
    method SetProgressMax (line 23) | public void SetProgressMax(int value)

FILE: Caesar/Diogenes/Forms/GenericPicker.Designer.cs
  class GenericPicker (line 4) | partial class GenericPicker
    method Dispose (line 15) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 30) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/GenericPicker.cs
  class GenericPicker (line 13) | public partial class GenericPicker : Form
    method GenericPicker (line 21) | public GenericPicker(string[][] table, string[] headers, int filterCol...
    method PresentRows (line 30) | private void PresentRows()
    method GenericPicker_Load (line 62) | private void GenericPicker_Load(object sender, EventArgs e)
    method dgvMain_CellDoubleClick (line 68) | private void dgvMain_CellDoubleClick(object sender, DataGridViewCellEv...
    method txtFilter_TextChanged (line 80) | private void txtFilter_TextChanged(object sender, EventArgs e)

FILE: Caesar/Diogenes/Forms/MainForm.Designer.cs
  class MainForm (line 3) | partial class MainForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/MainForm.cs
  class MainForm (line 18) | public partial class MainForm : Form
    method MainForm (line 22) | public MainForm()
    method MainForm_Load (line 32) | private void MainForm_Load(object sender, EventArgs e)
    method RedirectConsole (line 44) | private void RedirectConsole()
    method LoadContainers (line 50) | private void LoadContainers()
    method PostInitDebug (line 65) | private void PostInitDebug(CaesarContainer cbfContainer)
    method InitializeTree (line 69) | private void InitializeTree()
    method AddDiagServicesToNode (line 112) | private void AddDiagServicesToNode(TreeNode parentNode, ECUVariant var...
    method AddEcuMetadataToNode (line 188) | private void AddEcuMetadataToNode(TreeNode parentNode, CaesarContainer...
    method LoadTree (line 223) | private void LoadTree()
    method FixCALs (line 352) | private void FixCALs(CaesarContainer container)
    method TreeViewDoubleClickCheckIfSession (line 394) | private void TreeViewDoubleClickCheckIfSession(TreeNode node)
    method TreeViewDoubleClickCheckIfVariantDiag (line 417) | private void TreeViewDoubleClickCheckIfVariantDiag(TreeNode node)
    method PresentRunDiagDialog (line 468) | private void PresentRunDiagDialog(DiagService ds)
    method treeViewSelectVariantCoding (line 478) | private void treeViewSelectVariantCoding(TreeNode node)
    method tvMain_DoubleClick (line 495) | private void tvMain_DoubleClick(object sender, EventArgs e)
    method ProtocolPostConnect (line 595) | private void ProtocolPostConnect()
    method ShowAbout (line 604) | private void ShowAbout()
    method GetVersion (line 609) | public static string GetVersion()
    method aboutToolStripMenuItem_Click (line 616) | private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
    method exitToolStripMenuItem_Click (line 621) | private void exitToolStripMenuItem_Click(object sender, EventArgs e)
    method unloadExistingFilesToolStripMenuItem_Click (line 626) | private void unloadExistingFilesToolStripMenuItem_Click(object sender,...
    method loadCBFFilesToolStripMenuItem_Click (line 632) | private void loadCBFFilesToolStripMenuItem_Click(object sender, EventA...
    method TryLoadFile (line 644) | private void TryLoadFile(string fileName)
    method setSecurityLevelToolStripMenuItem_Click (line 658) | private void setSecurityLevelToolStripMenuItem_Click(object sender, Ev...
    method debugJ2534ToolStripMenuItem_Click (line 683) | private void debugJ2534ToolStripMenuItem_Click(object sender, EventArg...
    method j2534InterfacesToolStripMenuItem_DropDownOpening (line 688) | private void j2534InterfacesToolStripMenuItem_DropDownOpening(object s...
    method J2534InterfaceItem_Click (line 703) | private void J2534InterfaceItem_Click(object sender, EventArgs e)
    method disconnectToolStripMenuItem_Click (line 717) | private void disconnectToolStripMenuItem_Click(object sender, EventArg...
    method SetDisconnectedState (line 722) | private void SetDisconnectedState(bool refresh = true)
    method ConnectionStateChangedHandler (line 737) | private void ConnectionStateChangedHandler(string newStateDescription)
    method txtJ2534Input_KeyDown (line 743) | private void txtJ2534Input_KeyDown(object sender, KeyEventArgs e)
    method cFFExportFlashSegmentsToolStripMenuItem_Click (line 763) | private void cFFExportFlashSegmentsToolStripMenuItem_Click(object send...
    method fixClientAccessPermissionsToolStripMenuItem_Click (line 782) | private void fixClientAccessPermissionsToolStripMenuItem_Click(object ...
    method cFFFlashSplicerToolStripMenuItem_Click (line 794) | private void cFFFlashSplicerToolStripMenuItem_Click(object sender, Eve...
    method allowWriteVariantCodingToolStripMenuItem_Click (line 800) | private void allowWriteVariantCodingToolStripMenuItem_Click(object sen...
    method showTraceToolStripMenuItem_Click (line 806) | private void showTraceToolStripMenuItem_Click(object sender, EventArgs e)
    method clearConsoleToolStripMenuItem_Click (line 815) | private void clearConsoleToolStripMenuItem_Click(object sender, EventA...
    method tmrBlinkConnectionMenu_Tick (line 821) | private void tmrBlinkConnectionMenu_Tick(object sender, EventArgs e)
    method BlinkConnectionMenu (line 843) | private void BlinkConnectionMenu()
    method connectionToolStripMenuItem_DropDownOpening (line 849) | private void connectionToolStripMenuItem_DropDownOpening(object sender...
    method MainForm_FormClosing (line 855) | private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    method copyConsoleToolStripMenuItem_Click (line 860) | private void copyConsoleToolStripMenuItem_Click(object sender, EventAr...
    method uDSHexEditorToolStripMenuItem_Click (line 865) | private void uDSHexEditorToolStripMenuItem_Click(object sender, EventA...
    method preferencesToolStripMenuItem1_DropDownOpening (line 882) | private void preferencesToolStripMenuItem1_DropDownOpening(object send...
    method RefreshPreferencesDropdown (line 887) | private void RefreshPreferencesDropdown()
    method useLastSCNToolStripMenuItem_Click (line 907) | private void useLastSCNToolStripMenuItem_Click(object sender, EventArg...
    method writeZerosVediamoToolStripMenuItem_Click (line 913) | private void writeZerosVediamoToolStripMenuItem_Click(object sender, E...
    method useLastFingerprintToolStripMenuItem_Click (line 919) | private void useLastFingerprintToolStripMenuItem_Click(object sender, ...
    method customValueToolStripMenuItem_Click (line 925) | private void customValueToolStripMenuItem_Click(object sender, EventAr...
    method tvMain_DragEnter (line 932) | private void tvMain_DragEnter(object sender, DragEventArgs e)
    method tvMain_DragDrop (line 940) | private void tvMain_DragDrop(object sender, DragEventArgs e)
    method GetCurrentVariantInstance (line 950) | private ECUVariant GetCurrentVariantInstance()
    method diagnosticTroubleCodesDTCToolStripMenuItem_Click (line 976) | private void diagnosticTroubleCodesDTCToolStripMenuItem_Click(object s...
    method viewECUMetadataToolStripMenuItem_Click (line 999) | private void viewECUMetadataToolStripMenuItem_Click(object sender, Eve...
    method identifyECUToolStripMenuItem_Click (line 1004) | private void identifyECUToolStripMenuItem_Click(object sender, EventAr...
    method loadCompressedJsonToolStripMenuItem_Click (line 1016) | private void loadCompressedJsonToolStripMenuItem_Click(object sender, ...
    method PickContainer (line 1029) | private CaesarContainer PickContainer()
    method exportContainerAsCompressedJSONToolStripMenuItem_Click (line 1060) | private void exportContainerAsCompressedJSONToolStripMenuItem_Click(ob...
    method dSCDebugToolStripMenuItem_Click (line 1080) | private void dSCDebugToolStripMenuItem_Click(object sender, EventArgs e)
    method loadJSONToolStripMenuItem_Click (line 1093) | private void loadJSONToolStripMenuItem_Click(object sender, EventArgs e)
    method exportContainerAsJSONToolStripMenuItem_Click (line 1106) | private void exportContainerAsJSONToolStripMenuItem_Click(object sende...
    method genericDebugToolStripMenuItem_Click (line 1127) | private void genericDebugToolStripMenuItem_Click(object sender, EventA...
    method listVariantIDsToolStripMenuItem_Click (line 1183) | private void listVariantIDsToolStripMenuItem_Click(object sender, Even...
    method downloadBlocksToolStripMenuItem_Click (line 1205) | private void downloadBlocksToolStripMenuItem_Click(object sender, Even...
    method fixCBFChecksumToolStripMenuItem_Click (line 1216) | private void fixCBFChecksumToolStripMenuItem_Click(object sender, Even...

FILE: Caesar/Diogenes/Forms/PickDiagForm.Designer.cs
  class PickDiagForm (line 3) | partial class PickDiagForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/PickDiagForm.cs
  class PickDiagForm (line 15) | public partial class PickDiagForm : Form
    method PickDiagForm (line 19) | public PickDiagForm(DiagService[] diagServices)
    method PickDiagForm_Load (line 25) | private void PickDiagForm_Load(object sender, EventArgs e)
    method EnableDoubleBuffer (line 32) | public static void EnableDoubleBuffer(DataGridView dgv, bool setting)
    method PresentDiagServices (line 39) | private void PresentDiagServices()
    method txtFilter_TextChanged (line 97) | private void txtFilter_TextChanged(object sender, EventArgs e)
    method dgvMain_CellDoubleClick (line 102) | private void dgvMain_CellDoubleClick(object sender, DataGridViewCellEv...

FILE: Caesar/Diogenes/Forms/RunDiagForm.Designer.cs
  class RunDiagForm (line 3) | partial class RunDiagForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/RunDiagForm.cs
  class RunDiagForm (line 14) | public partial class RunDiagForm : Form
    method RunDiagForm (line 19) | public RunDiagForm(DiagService diagService)
    method RunDiagForm_Load (line 26) | private void RunDiagForm_Load(object sender, EventArgs e)
    method TrimIntegerDumps (line 42) | private void TrimIntegerDumps()
    method CheckBitAlignment (line 58) | private bool CheckBitAlignment()
    method PresentDiagService (line 79) | private void PresentDiagService()
    method btnApply_Click (line 149) | private void btnApply_Click(object sender, EventArgs e)

FILE: Caesar/Diogenes/Forms/SecurityLevelForm.Designer.cs
  class SecurityLevelForm (line 3) | partial class SecurityLevelForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/SecurityLevelForm.cs
  class SecurityLevelForm (line 15) | public partial class SecurityLevelForm : Form
    method SecurityLevelForm (line 23) | public SecurityLevelForm(DllContext context)
    method PresentKeys (line 29) | private void PresentKeys(byte[] seed)
    method SecurityLevelForm_Load (line 53) | private void SecurityLevelForm_Load(object sender, EventArgs e)
    method txtCodingString_TextChanged (line 61) | private void txtCodingString_TextChanged(object sender, EventArgs e)
    method TryRefreshKey (line 65) | public void TryRefreshKey()
    method dgvMain_CellDoubleClick (line 94) | private void dgvMain_CellDoubleClick(object sender, DataGridViewCellEv...
    method RequestSeed (line 115) | private void RequestSeed(int accessLevel)

FILE: Caesar/Diogenes/Forms/TraceForm.Designer.cs
  class TraceForm (line 4) | partial class TraceForm
    method Dispose (line 15) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 30) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/TraceForm.cs
  class TraceForm (line 15) | public partial class TraceForm : Form
    method TraceForm (line 19) | public TraceForm(MainForm parentMainForm)
    method TraceForm_Load (line 25) | private void TraceForm_Load(object sender, EventArgs e)
    method RefreshTimer_Tick (line 32) | private void RefreshTimer_Tick(object sender, EventArgs e)
    method copyAllToolStripMenuItem_Click (line 50) | private void copyAllToolStripMenuItem_Click(object sender, EventArgs e)
    method saveToFileToolStripMenuItem_Click (line 55) | private void saveToFileToolStripMenuItem_Click(object sender, EventArg...

FILE: Caesar/Diogenes/Forms/UDSHexEditor.Designer.cs
  class UDSHexEditor (line 4) | partial class UDSHexEditor
    method Dispose (line 15) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 30) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/UDSHexEditor.cs
  class UDSHexEditor (line 17) | public partial class UDSHexEditor : Form
    method UDSHexEditor (line 22) | public UDSHexEditor(ECUConnection connection)
    method UDSHexEditor_Load (line 46) | private void UDSHexEditor_Load(object sender, EventArgs e)
    method GatewayWait (line 51) | private static void GatewayWait()
    method btnRead_Click (line 57) | private void btnRead_Click(object sender, EventArgs e)
    method CreateReadCommand (line 136) | private List<byte> CreateReadCommand(byte readCmd, byte alfid, long so...
    method CreateWriteCommand (line 148) | private List<byte> CreateWriteCommand(byte writeCmd, long destAddress,...
    method ValueToBEByteArrayConstrained (line 168) | private List<byte> ValueToBEByteArrayConstrained(long inValue, int size)
    method ValueToBEByteArray (line 181) | private List<byte> ValueToBEByteArray(long inValue)
    method GetMemoryDigitCount (line 193) | private static int GetMemoryDigitCount(int value)
    method GetAddressAndLengthFormatIdentifier (line 204) | private static byte GetAddressAndLengthFormatIdentifier(int addressSiz...
    method FetchAndValidateInput (line 231) | private bool FetchAndValidateInput(out uint sourceAddress_, out uint d...
    method BytearrayEqual (line 269) | private bool BytearrayEqual(byte[] a, byte[] b)
    method btnWrite_Click (line 285) | private void btnWrite_Click(object sender, EventArgs e)
    method btnSaveToFile_Click (line 352) | private void btnSaveToFile_Click(object sender, EventArgs e)

FILE: Caesar/Diogenes/Forms/VCForm.Designer.cs
  class VCForm (line 3) | partial class VCForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: Caesar/Diogenes/Forms/VCForm.cs
  class VCForm (line 15) | public partial class VCForm : Form
    method VCForm (line 29) | public VCForm(CaesarContainer container, string ecuName, string varian...
    method GetLargestPreparation (line 95) | public static DiagPreparation GetLargestPreparation(List<List<DiagPrep...
    method GetLargestPreparation (line 122) | public static DiagPreparation GetLargestPreparation(List<DiagPreparati...
    method VCSanityCheck (line 143) | private void VCSanityCheck()
    method PresentVC (line 155) | private void PresentVC()
    method ReinterpretVC (line 161) | private void ReinterpretVC()
    method IntepretVC (line 167) | private void IntepretVC()
    method VCForm_Load (line 221) | private void VCForm_Load(object sender, EventArgs e)
    method SetDoubleBuffer (line 226) | static void SetDoubleBuffer(Control ctl, bool DoubleBuffered)
    method btnApply_Click (line 233) | private void btnApply_Click(object sender, EventArgs e)
    method btnReinterpret_Click (line 252) | private void btnReinterpret_Click(object sender, EventArgs e)
    method rbHex_CheckedChanged (line 263) | private void rbHex_CheckedChanged(object sender, EventArgs e)
    method radioButton1_CheckedChanged (line 268) | private void radioButton1_CheckedChanged(object sender, EventArgs e)
    method btnCopy_Click (line 273) | private void btnCopy_Click(object sender, EventArgs e)
    method contextMenuStrip1_Opening (line 278) | private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
    method ShowPickerDialog (line 331) | private void ShowPickerDialog(string fragmentName, VCFragment fragment)
    method VCContextMenu_Click (line 348) | private void VCContextMenu_Click(object sender, EventArgs e)
    method SelectVC (line 356) | private void SelectVC(string fragmentName, string fragmentValue)

FILE: Caesar/Diogenes/Preferences.cs
  class Preferences (line 11) | public class Preferences
    type PreferenceKey (line 13) | public enum PreferenceKey
    method InitializePreferences (line 23) | public static void InitializePreferences()
    method GetValue (line 34) | public static string GetValue(PreferenceKey key)
    method SetValue (line 51) | public static void SetValue(PreferenceKey key, string newValue, bool s...
    method GetPreferencesFilePath (line 73) | private static string GetPreferencesFilePath()
    method GetPreferencesDirectory (line 77) | private static string GetPreferencesDirectory()
    method SerializeAndSavePreferences (line 82) | public static void SerializeAndSavePreferences()
    method LoadAndDeserializePreferences (line 98) | public static bool LoadAndDeserializePreferences()

FILE: Caesar/Diogenes/Program.cs
  class Program (line 9) | static class Program
    method Main (line 14) | [STAThread]

FILE: Caesar/Diogenes/Properties/Resources.Designer.cs
  class Resources (line 22) | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resource...
    method Resources (line 31) | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Mic...

FILE: Caesar/Diogenes/Properties/Settings.Designer.cs
  class Settings (line 15) | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]

FILE: Caesar/Diogenes/Reports/DTCReport.cs
  class DTCReport (line 12) | public class DTCReport
    method CreateDTCReport (line 15) | public static void CreateDTCReport(List<DTCContext> dtcContexts, ECUCo...

FILE: Caesar/Diogenes/Reports/VCReport.cs
  class VCReport (line 12) | public class VCReport
    method treeViewSelectVariantCodingBackup (line 15) | public static void treeViewSelectVariantCodingBackup(TreeNode node, EC...

FILE: Caesar/Diogenes/SecurityAccess/DllContext.cs
  class DllContext (line 14) | public class DllContext
    method DllContext (line 30) | public DllContext(string filePath, bool runHash = true)
    method LoadAdditionalDataFromDllCalls (line 90) | public void LoadAdditionalDataFromDllCalls()
    method GenerateKeyAuto (line 109) | public string GenerateKeyAuto(uint securityLevel, byte[] seed)
    method GetECUName (line 125) | public string GetECUName()
    method GetComment (line 136) | public string GetComment()
    method GetConfiguredAccessTypes (line 147) | public List<uint> GetConfiguredAccessTypes()
    method GetSeedLength (line 159) | public int GetSeedLength(uint securityLevel)
    method GetKeyLength (line 169) | public int GetKeyLength(uint securityLevel)
    method GenerateKey (line 180) | private byte[] GenerateKey(byte[] seed, uint securityLevel, bool addOp...
    method UnloadLibrary (line 209) | public void UnloadLibrary()

FILE: Caesar/Diogenes/SecurityAccess/ExportDefinition.cs
  class ExportDefinition (line 10) | class ExportDefinition
    type VKeyGenResultEx (line 35) | public enum VKeyGenResultEx

FILE: Caesar/Diogenes/SecurityAccess/SecurityAutoLogin.cs
  class SecurityAutoLogin (line 13) | public class SecurityAutoLogin
    method ReceiveSecurityResponse (line 15) | public static void ReceiveSecurityResponse(byte[] response, ECU parent...
    method RequestUnlock (line 45) | private static bool RequestUnlock(ECUConnection connection, int receiv...
    method QueryUnlockEcu (line 61) | public static bool QueryUnlockEcu(byte[] seed, string ecuName, int lev...
    method RunProcessCaptureOutput (line 91) | private static string RunProcessCaptureOutput(string filePath, string ...
    method PromptClipboardCopyOfSeed (line 135) | private static void PromptClipboardCopyOfSeed(string seed)

FILE: Caesar/Diogenes/Simulation/SimulatedDevice.cs
  class SimulatedDevice (line 10) | public class SimulatedDevice
    method ReceiveRequest (line 12) | public virtual byte[] ReceiveRequest(IEnumerable<byte> request)

FILE: Caesar/Diogenes/Simulation/Simulated_CRD3.cs
  class Simulated_CRD3 (line 11) | public class Simulated_CRD3 : SimulatedDevice
    type UDS (line 14) | public enum UDS : byte
    type NR (line 46) | public enum NR : byte
    type Identifier (line 91) | public enum Identifier : ushort
    type Vendor (line 100) | public enum Vendor : byte
    method Simulated_CRD3 (line 244) | public Simulated_CRD3()
    method WriteByte (line 271) | public void WriteByte(byte inByte)
    method WriteUint16 (line 275) | public void WriteUint16(ushort inValue)
    method WriteInt16 (line 280) | public void WriteInt16(short inValue)
    method WriteUint32 (line 285) | public void WriteUint32(ushort inValue)
    method WriteInt32 (line 292) | public void WriteInt32(int inValue)
    method WriteByteArray (line 300) | public void WriteByteArray(byte[] inValue)
    method CreateNegativeResponse (line 306) | public byte[] CreateNegativeResponse(UDS callingFunction, NR reason)
    method MemoryStreamWriterToArray (line 312) | public byte[] MemoryStreamWriterToArray(BinaryWriter writer)
    method ReceiveRequest (line 317) | public override byte[] ReceiveRequest(IEnumerable<byte> request)
    method CRC16ARC (line 407) | public static ushort CRC16ARC(byte[] inData)

FILE: Caesar/Diogenes/TextboxWriter.cs
  class TextboxWriter (line 11) | public class TextboxWriter : TextWriter
    method TextboxWriter (line 19) | public TextboxWriter(TextBox inputTextbox)
    method Timer_Tick (line 28) | private void Timer_Tick(object sender, EventArgs e)
    method Write (line 41) | public override void Write(char value)
    method Write (line 50) | public override void Write(string value)
    method Clear (line 59) | public void Clear()

FILE: Caesar/Diogenes/UnmanagedUtility.cs
  class UnmanagedUtility (line 11) | class UnmanagedUtility
    method SymInitialize (line 17) | [DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unico...
    method SymCleanup (line 21) | [DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unico...
    method SymLoadModuleEx (line 25) | [DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unico...
    method SymEnumerateSymbols64 (line 28) | [DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unico...
    method LoadLibrary (line 39) | [DllImport("kernel32.dll")]
    method GetProcAddress (line 42) | [DllImport("kernel32.dll")]
    method FreeLibrary (line 45) | [DllImport("kernel32.dll")]
    method SendMessage (line 53) | [DllImport("user32.dll", CharSet = CharSet.Auto)]
    method SendMessage (line 56) | [DllImport("user32.dll", CharSet = CharSet.Auto)]
    method SymbolEnumeratedCallback (line 61) | public static bool SymbolEnumeratedCallback(string name, ulong address...
    method EnumerateDllExports (line 68) | private static bool EnumerateDllExports(string modulePath)
    method GetExports (line 105) | public static List<string> GetExports(string modulePath)
    method DumpExportsToConsole (line 117) | public static void DumpExportsToConsole(string modulePath)

FILE: Caesar/Diogenes/VariantCoding.cs
  class VariantCoding (line 11) | public class VariantCoding
    method ExecVCWrite (line 14) | private static void ExecVCWrite(byte[] request, DiagService service, E...
    method DoVariantCoding (line 46) | public static void DoVariantCoding(ECUConnection connection, VCForm vc...

FILE: Caesar/Trafo/Program.cs
  class Program (line 10) | class Program
    method ReadScales (line 14) | static void ReadScales (CaesarContainer container, DiagPresentation pr...
    method ReadPreparation (line 37) | static void ReadPreparation (CaesarContainer container, DiagPreparatio...
    method ReadDiagService (line 66) | static void ReadDiagService (CaesarContainer container, DiagService di...
    method ReadECUVariant (line 100) | static void ReadECUVariant (CaesarContainer container, ECUVariant vari...
    method Main (line 201) | static void Main(string[] args)
    method GetVersion (line 294) | public static string GetVersion()
Condensed preview — 110 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,205K chars).
[
  {
    "path": ".gitignore",
    "chars": 6002,
    "preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## G"
  },
  {
    "path": "Caesar/Caesar/App.config",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".N"
  },
  {
    "path": "Caesar/Caesar/BitUtility.cs",
    "chars": 8926,
    "preview": "using System;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace Caesar\n{\n    /// <summary>\n    /// Ut"
  },
  {
    "path": "Caesar/Caesar/CFFHeader.cs",
    "chars": 3832,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Caesar/CTFHeader.cs",
    "chars": 2849,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/CTFLanguage.cs",
    "chars": 2805,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/Caesar.csproj",
    "chars": 4167,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "Caesar/Caesar/CaesarContainer.cs",
    "chars": 10303,
    "preview": "using Newtonsoft.Json;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.IO.Compression;\nus"
  },
  {
    "path": "Caesar/Caesar/CaesarReader.cs",
    "chars": 13285,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Caesar/CaesarStructure.cs",
    "chars": 10140,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Caesar/ComParameter.cs",
    "chars": 3056,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/DSCContext.cs",
    "chars": 8558,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Caesar/DTC.cs",
    "chars": 2844,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Caesar/DiagPreparation.cs",
    "chars": 18841,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/DiagPresentation.cs",
    "chars": 22597,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/DiagService.cs",
    "chars": 19515,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/ECU.cs",
    "chars": 31711,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Caesar/ECUInterface.cs",
    "chars": 3509,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/ECUInterfaceSubtype.cs",
    "chars": 4829,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/ECUVariant.cs",
    "chars": 22099,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Caesar/ECUVariantPattern.cs",
    "chars": 4806,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/Flash/CaesarFlashContainer.cs",
    "chars": 7016,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Caesar/Flash/FlashDataBlock.cs",
    "chars": 8393,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Caesar/Flash/FlashDescriptionHeader.cs",
    "chars": 3129,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/Flash/FlashHeader.cs",
    "chars": 6616,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Caesar/Flash/FlashSecurity.cs",
    "chars": 3136,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Caesar/Flash/FlashSegment.cs",
    "chars": 2794,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Caesar/Program.cs",
    "chars": 1556,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/Properties/AssemblyInfo.cs",
    "chars": 1380,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
  },
  {
    "path": "Caesar/Caesar/Scale.cs",
    "chars": 3078,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/StubHeader.cs",
    "chars": 885,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "Caesar/Caesar/VCDomain.cs",
    "chars": 8329,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/VCFragment.cs",
    "chars": 13697,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/VCSubfragment.cs",
    "chars": 3287,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Caesar/packages.config",
    "chars": 138,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Newtonsoft.Json\" version=\"12.0.3\" targetFramework=\"net"
  },
  {
    "path": "Caesar/Caesar.sln",
    "chars": 2032,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.3030"
  },
  {
    "path": "Caesar/Diogenes/App.config",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".N"
  },
  {
    "path": "Caesar/Diogenes/DiagnosticProtocol/BaseProtocol.cs",
    "chars": 1901,
    "preview": "using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Thread"
  },
  {
    "path": "Caesar/Diogenes/DiagnosticProtocol/KW2C3PE.cs",
    "chars": 5148,
    "preview": "using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Thread"
  },
  {
    "path": "Caesar/Diogenes/DiagnosticProtocol/UDS.cs",
    "chars": 19758,
    "preview": "using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Thread"
  },
  {
    "path": "Caesar/Diogenes/DiagnosticProtocol/UnsupportedProtocol.cs",
    "chars": 647,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "Caesar/Diogenes/Diogenes.csproj",
    "chars": 12998,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "Caesar/Diogenes/ECUConnection.cs",
    "chars": 24936,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Diogenes/ECUFlashMetadata.cs",
    "chars": 578,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "Caesar/Diogenes/ECUIdentification.cs",
    "chars": 5971,
    "preview": "using Caesar;\nusing SAE.J2534;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nus"
  },
  {
    "path": "Caesar/Diogenes/ECUMetadata.cs",
    "chars": 10298,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "Caesar/Diogenes/Forms/AboutForm.Designer.cs",
    "chars": 8199,
    "preview": "\nnamespace Diogenes\n{\n    partial class AboutForm\n    {\n        /// <summary>\n        /// Required designer variable.\n "
  },
  {
    "path": "Caesar/Diogenes/Forms/AboutForm.cs",
    "chars": 742,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nu"
  },
  {
    "path": "Caesar/Diogenes/Forms/AboutForm.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Forms/BlockDownload.Designer.cs",
    "chars": 16389,
    "preview": "\nnamespace Diogenes\n{\n    partial class BlockDownload\n    {\n        /// <summary>\n        /// Required designer variabl"
  },
  {
    "path": "Caesar/Diogenes/Forms/BlockDownload.cs",
    "chars": 16623,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nu"
  },
  {
    "path": "Caesar/Diogenes/Forms/BlockDownload.resx",
    "chars": 7703,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Forms/DTCForm.Designer.cs",
    "chars": 11195,
    "preview": "\nnamespace Diogenes\n{\n    partial class DTCForm\n    {\n        /// <summary>\n        /// Required designer variable.\n   "
  },
  {
    "path": "Caesar/Diogenes/Forms/DTCForm.cs",
    "chars": 12588,
    "preview": "using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing Sys"
  },
  {
    "path": "Caesar/Diogenes/Forms/DTCForm.resx",
    "chars": 7898,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Forms/FlashSplicer.Designer.cs",
    "chars": 8886,
    "preview": "\nnamespace Diogenes\n{\n    partial class FlashSplicer\n    {\n        /// <summary>\n        /// Required designer variable"
  },
  {
    "path": "Caesar/Diogenes/Forms/FlashSplicer.cs",
    "chars": 15673,
    "preview": "using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing Sys"
  },
  {
    "path": "Caesar/Diogenes/Forms/FlashSplicer.resx",
    "chars": 7898,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Forms/GenericLoader.Designer.cs",
    "chars": 2234,
    "preview": "\nnamespace Diogenes\n{\n    partial class GenericLoader\n    {\n        /// <summary>\n        /// Required designer variabl"
  },
  {
    "path": "Caesar/Diogenes/Forms/GenericLoader.cs",
    "chars": 599,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nu"
  },
  {
    "path": "Caesar/Diogenes/Forms/GenericLoader.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Forms/GenericPicker.Designer.cs",
    "chars": 4002,
    "preview": "\nnamespace Diogenes\n{\n    partial class GenericPicker\n    {\n        /// <summary>\n        /// Required designer variabl"
  },
  {
    "path": "Caesar/Diogenes/Forms/GenericPicker.cs",
    "chars": 2810,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nu"
  },
  {
    "path": "Caesar/Diogenes/Forms/GenericPicker.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Forms/MainForm.Designer.cs",
    "chars": 40211,
    "preview": "namespace Diogenes\n{\n    partial class MainForm\n    {\n        /// <summary>\n        /// Required designer variable.\n   "
  },
  {
    "path": "Caesar/Diogenes/Forms/MainForm.cs",
    "chars": 52009,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nu"
  },
  {
    "path": "Caesar/Diogenes/Forms/MainForm.resx",
    "chars": 310475,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Forms/PickDiagForm.Designer.cs",
    "chars": 4031,
    "preview": "namespace Diogenes\n{\n    partial class PickDiagForm\n    {\n        /// <summary>\n        /// Required designer variable."
  },
  {
    "path": "Caesar/Diogenes/Forms/PickDiagForm.cs",
    "chars": 4640,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nu"
  },
  {
    "path": "Caesar/Diogenes/Forms/PickDiagForm.resx",
    "chars": 7703,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Forms/RunDiagForm.Designer.cs",
    "chars": 8016,
    "preview": "namespace Diogenes\n{\n    partial class RunDiagForm\n    {\n        /// <summary>\n        /// Required designer variable.\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/RunDiagForm.cs",
    "chars": 6212,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nu"
  },
  {
    "path": "Caesar/Diogenes/Forms/RunDiagForm.resx",
    "chars": 7703,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Forms/SecurityLevelForm.Designer.cs",
    "chars": 6064,
    "preview": "namespace Diogenes\n{\n    partial class SecurityLevelForm\n    {\n        /// <summary>\n        /// Required designer vari"
  },
  {
    "path": "Caesar/Diogenes/Forms/SecurityLevelForm.cs",
    "chars": 4452,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nu"
  },
  {
    "path": "Caesar/Diogenes/Forms/SecurityLevelForm.resx",
    "chars": 7703,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Forms/TraceForm.Designer.cs",
    "chars": 5639,
    "preview": "\nnamespace Diogenes\n{\n    partial class TraceForm\n    {\n        /// <summary>\n        /// Required designer variable.\n "
  },
  {
    "path": "Caesar/Diogenes/Forms/TraceForm.cs",
    "chars": 2174,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nu"
  },
  {
    "path": "Caesar/Diogenes/Forms/TraceForm.resx",
    "chars": 7898,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Forms/UDSHexEditor.Designer.cs",
    "chars": 21194,
    "preview": "\nnamespace Diogenes\n{\n    partial class UDSHexEditor\n    {\n        /// <summary>\n        /// Required designer variable"
  },
  {
    "path": "Caesar/Diogenes/Forms/UDSHexEditor.cs",
    "chars": 13627,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nu"
  },
  {
    "path": "Caesar/Diogenes/Forms/UDSHexEditor.resx",
    "chars": 7703,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Forms/VCForm.Designer.cs",
    "chars": 10469,
    "preview": "namespace Diogenes\n{\n    partial class VCForm\n    {\n        /// <summary>\n        /// Required designer variable.\n     "
  },
  {
    "path": "Caesar/Diogenes/Forms/VCForm.cs",
    "chars": 14715,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nu"
  },
  {
    "path": "Caesar/Diogenes/Forms/VCForm.resx",
    "chars": 7905,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Preferences.cs",
    "chars": 3882,
    "preview": "using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nus"
  },
  {
    "path": "Caesar/Diogenes/Program.cs",
    "chars": 510,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows.F"
  },
  {
    "path": "Caesar/Diogenes/Properties/AssemblyInfo.cs",
    "chars": 1384,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
  },
  {
    "path": "Caesar/Diogenes/Properties/Resources.Designer.cs",
    "chars": 13172,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "Caesar/Diogenes/Properties/Resources.resx",
    "chars": 12727,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "Caesar/Diogenes/Properties/Settings.Designer.cs",
    "chars": 1063,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "Caesar/Diogenes/Properties/Settings.settings",
    "chars": 240,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\""
  },
  {
    "path": "Caesar/Diogenes/Reports/DTCReport.cs",
    "chars": 4457,
    "preview": "using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nus"
  },
  {
    "path": "Caesar/Diogenes/Reports/VCReport.cs",
    "chars": 6318,
    "preview": "using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nus"
  },
  {
    "path": "Caesar/Diogenes/SecurityAccess/DllContext.cs",
    "chars": 8951,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing Sys"
  },
  {
    "path": "Caesar/Diogenes/SecurityAccess/ExportDefinition.cs",
    "chars": 1775,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.T"
  },
  {
    "path": "Caesar/Diogenes/SecurityAccess/SecurityAutoLogin.cs",
    "chars": 5522,
    "preview": "using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.L"
  },
  {
    "path": "Caesar/Diogenes/Simulation/SimulatedDevice.cs",
    "chars": 510,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "Caesar/Diogenes/Simulation/Simulated_CRD3.cs",
    "chars": 19048,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "Caesar/Diogenes/TextboxWriter.cs",
    "chars": 1932,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "Caesar/Diogenes/UnmanagedUtility.cs",
    "chars": 4994,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Runtime.Inter"
  },
  {
    "path": "Caesar/Diogenes/VariantCoding.cs",
    "chars": 12875,
    "preview": "using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Thread"
  },
  {
    "path": "Caesar/Diogenes/packages.config",
    "chars": 224,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Be.Windows.Forms.HexBox\" version=\"1.6.1\" targetFramewo"
  },
  {
    "path": "Caesar/Trafo/App.config",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".N"
  },
  {
    "path": "Caesar/Trafo/Program.cs",
    "chars": 12487,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Caesar;\nusing System.IO;\nusing Newtonsoft.Json;"
  },
  {
    "path": "Caesar/Trafo/Properties/AssemblyInfo.cs",
    "chars": 1378,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
  },
  {
    "path": "Caesar/Trafo/Trafo.csproj",
    "chars": 2949,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "Caesar/Trafo/packages.config",
    "chars": 138,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Newtonsoft.Json\" version=\"12.0.3\" targetFramework=\"net"
  },
  {
    "path": "LICENSE",
    "chars": 1067,
    "preview": "MIT License\n\nCopyright (c) 2020 JinGen Lim\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "README.md",
    "chars": 6064,
    "preview": "![CaesarSuite Banner](https://raw.githubusercontent.com/jglim/CaesarSuite/main/docs/resources/caesarsuite-banner.png)\n\n#"
  }
]

About this extraction

This page contains the full source code of the jglim/CaesarSuite GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 110 files (1.1 MB), approximately 345.4k tokens, and a symbol index with 634 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!