public void WriteOffViewFormat(string fileName, NativeProfilerUnit unit)
        {
            StreamWriter m_sw = new StreamWriter(fileName, false, Encoding.Default);

            m_sw.WriteLine(c_line, "Calls", "Level", "Function", "Module", "Time", "Type", "Warnings");

            uint startLevel = unit.NestingLevel;
            uint index      = unit.NItem;
            uint returnTime = unit.ReturnTime;
            uint maxNodeN   = GetNMax();

            while (index < maxNodeN && ((NativeProfilerUnit)htN[index]).ReturnTime <= returnTime)
            {
                m_sw.WriteLine(c_line, "1", (GetUnitNestingLevel(index) - startLevel).ToString(), GetUnitFunctionName(index), "0", GetUnitInclTime(index), " ", " ");
                index++;
            }
            WriteGibberishForOffView(m_sw);
            m_sw.WriteLine();
            m_sw.WriteLine("STATISTICS:");
            m_sw.WriteLine("Total Threads = 0");
            m_sw.WriteLine("Maximum Concurrent Threads = 1");
            m_sw.WriteLine("Total Function Nodes = {0}", (index - unit.NItem));
            m_sw.WriteLine("Total Function Calls = {0}", (index - unit.NItem));
            m_sw.WriteLine("Memory Buffer Used = 1K");
            m_sw.WriteLine("Memory Buffer Allocated = 1K");
            m_sw.WriteLine("Memory Buffer Reserved = 2K");
            m_sw.Flush();
            m_sw.Close();
        }
 public string GetUnitFunctionName(NativeProfilerUnit unit)
 {
     return((string)htFunctionNames[unit.FunctionAddress]);
 }
        public NativeProfiler(Stream m_tInput, string mapFileName, bool b_checkBlockBegin)
        {
            bool needRestart  = true;
            long streamLength = m_tInput.Length;
            uint nRestarts    = 0;

            while (needRestart == true && streamLength > 0)
            {
                needRestart = false;
                try
                {
                    NativeProfilerUnit[] htN_temp = new NativeProfilerUnit[streamLength];
                    htFunctionNames = new Hashtable();
                    htN             = new NativeProfilerUnit[streamLength];
                    htInclTime      = new uint[streamLength];
                    htExclTime      = new uint[streamLength];
                    Stack  stack  = new Stack(8096);
                    byte[] bArray = new byte[20];
                    m_tInput.Seek(0, SeekOrigin.Begin);
                    nItems       = 0;
                    totalRuntime = 0;
                    long n = 0;
                    uint level = 0;
                    uint address = 0, time = 0;
                    uint checkValue = 0;

                    NativeProfilerUnit unit;

                    if (b_checkBlockBegin == true)
                    {
                        while (streamLength - m_tInput.Position >= 4 && checkValue != 0xbaadf00d)
                        {
                            m_tInput.Read(bArray, 0, 4);

                            checkValue = BitConverter.ToUInt32(bArray, 0);
                            if (checkValue != 0xbaadf00d)
                            {
                                m_tInput.Seek(-3, SeekOrigin.Current);
                            }
                            else
                            {
                                m_tInput.Read(bArray, 0, 4);
                                engineTimeOffset = BitConverter.ToUInt32(bArray, 0);
                            }
                        }
                    }

                    while (streamLength - m_tInput.Position >= 8)
                    {
                        m_tInput.Read(bArray, 0, 8);
                        address = BitConverter.ToUInt32(bArray, 0);
                        time    = BitConverter.ToUInt32(bArray, 4);
                        if (address != 0xbaadf00d && address != 0xd00fdaab && time != 0xbaadf00d && time != 0xd00fdaab)
                        {
                            if ((address & 1) == 0) // if the address is even then it is a push opcode
                            {
                                unit                 = new NativeProfilerUnit();
                                unit.EntryTime       = time;
                                unit.FunctionAddress = address;
                                unit.NestingLevel    = level;
                                unit.ReturnTime      = 0xffffffff;
                                htN_temp[n]          = unit;
                                stack.Push(unit);
                                n++;
                                level++;
                                // Adds a reference that a key for 'address' exists in htFunctionNames.
                                htFunctionNames[address] = null;
                            }
                            else if (stack.Count > 0) // if the address is odd then it is a pop opcode
                            {
                                unit            = (NativeProfilerUnit)stack.Pop();
                                unit.ReturnTime = time;
                                level--;
                            }
                        }
                        else if (time == 0xbaadf00d)
                        {
                            if (m_tInput.Length - m_tInput.Position >= 4)
                            {
                                m_tInput.Seek(4, SeekOrigin.Current);
                            }
                        }
                        else if (address == 0xd00fdaab || time == 0xd00fdaab)
                        {
                            if (time != 0xbaadf00d)
                            {
                                m_tInput.Seek(-3, SeekOrigin.Current);
                            }
                            while (streamLength - m_tInput.Position >= 4 && time != 0xbaadf00d)
                            {
                                m_tInput.Read(bArray, 0, 4);
                                time = BitConverter.ToUInt32(bArray, 0);
                                if (time != 0xbaadf00d)
                                {
                                    m_tInput.Seek(-3, SeekOrigin.Current);
                                }
                            }
                            m_tInput.Read(bArray, 0, 4);
                        }
                    }

                    OpenMAPFile(mapFileName);
                    totalRuntime = 0;

                    // Do some simple data consistancy check
                    // We use time, and check that the level of the next unit - level of the previous level is <= 1;
                    uint index = 0;
                    unit         = (NativeProfilerUnit)htN_temp[index];
                    minimalLevel = 0xffffffff;
                    while (unit != null)
                    {
                        if (unit.ReturnTime > unit.EntryTime && unit.ReturnTime != 0xffffffff &&
                            unit.EntryTime != 0xffffffff && htFunctionNames[unit.FunctionAddress] != null &&
                            (nItems == 0 || nItems != 0 && ((int)unit.NestingLevel - (int)htN[nItems - 1].NestingLevel <= 1)))
                        {
                            htN[nItems] = unit;
                            unit.NItem  = nItems;
                            nItems++;
                            if (unit.NestingLevel < minimalLevel)
                            {
                                minimalLevel = unit.NestingLevel;
                            }
                        }
                        else
                        {
                            if (nItems != 0)
                            {
                                // If the node after the last one is not correct then destroy the last node too.
                                htN[nItems - 1] = null;
                                nItems--;
                            }
                            break;
                        }
                        index++;
                        unit = (NativeProfilerUnit)htN_temp[index];
                    }
                    if (minimalLevel == 0xffffffff)
                    {
                        minimalLevel = 0;
                    }


                    // The last nodes seems to be scratched sometimes.
                    // So we ignore everything from the node after the last one until the node of level minimalLevel,
                    // or the node which is null (if it is not already that one).
                    NativeProfilerUnit lastNode;
                    uint lastLevel = minimalLevel;
                    index = nItems;
                    do
                    {
                        lastNode = (NativeProfilerUnit)htN[index];
                        if (lastNode != null)
                        {
                            lastLevel = lastNode.NestingLevel;
                        }
                        index--;
                    }while (lastNode != null && lastLevel > minimalLevel);
                    if (index != nItems - 1)
                    {
                        lastNode = (NativeProfilerUnit)htN[index];
                    }

                    unit = (NativeProfilerUnit)htN[(uint)0];

                    index = 0;
                    while (unit != null && unit != lastNode)
                    {
                        index++;
                        unit = (NativeProfilerUnit)htN[index];
                    }

                    nItems      = index;
                    htN[nItems] = null;

                    // Count inclusive, exclusive time
                    for (index = 0; index < nItems; index++)
                    {
                        unit = GetUnit(index);
                        uint entryTime  = unit.EntryTime;
                        uint returnTime = unit.ReturnTime;
                        level = unit.NestingLevel;
                        uint count    = index + 1;
                        long exclTime = (long)unit.ExecutionTime - (long)EngineTimeOffset;
                        while (count < nItems && htN[count] != null && ((NativeProfilerUnit)htN[count]).ReturnTime < returnTime && ((NativeProfilerUnit)htN[count]).EntryTime < returnTime)
                        {
                            if (((NativeProfilerUnit)htN[count]).NestingLevel == level + 1)
                            {
                                exclTime = exclTime - ((NativeProfilerUnit)htN[count]).ExecutionTime;
                            }
                            count++;
                        }

                        if (exclTime < 0)
                        {
                            exclTime = 0;
                        }
                        htExclTime[index] = (uint)exclTime;
                    }

                    for (index = nItems - 1; (int)index >= 0; index--)
                    {
                        unit = GetUnit(index);
                        uint entryTime  = unit.EntryTime;
                        uint returnTime = unit.ReturnTime;
                        level = unit.NestingLevel;
                        uint count    = index + 1;
                        long inclTime = 0;
                        while (count < nItems && htN[count] != null && ((NativeProfilerUnit)htN[count]).ReturnTime < returnTime && ((NativeProfilerUnit)htN[count]).EntryTime < returnTime)
                        {
                            if (((NativeProfilerUnit)htN[count]).NestingLevel == level + 1)
                            {
                                inclTime = inclTime + htInclTime[count];
                            }
                            count++;
                        }

                        inclTime         += htExclTime[index];
                        htInclTime[index] = (uint)(inclTime);
                        if (unit.NestingLevel == minimalLevel)
                        {
                            totalRuntime += (uint)inclTime;
                        }
                    }
                }
                catch (System.OutOfMemoryException)
                {
                    if (nRestarts == 0)
                    {
                        System.Windows.Forms.MessageBox.Show("Out of memory. Will try to strip data until load of data is possible.");
                    }
                    needRestart   = true;
                    streamLength /= 2;
                    nRestarts++;
                }
                catch (Exception e)
                {
                    System.Windows.Forms.MessageBox.Show("Unfortunately there was an error during decoding data. Exception sent: " + e.ToString());
                }
            }
        }
        public void WriteOffViewFormat(string fileName, NativeProfilerUnit unit)
        {            
            StreamWriter m_sw = new StreamWriter(fileName, false, Encoding.Default);
            m_sw.WriteLine(c_line, "Calls", "Level", "Function", "Module", "Time", "Type", "Warnings");

            uint startLevel = unit.NestingLevel;
            uint index = unit.NItem;
            uint returnTime = unit.ReturnTime;
            uint maxNodeN = GetNMax();
            while (index < maxNodeN && ((NativeProfilerUnit)htN[index]).ReturnTime <= returnTime)
            {
                m_sw.WriteLine(c_line, "1", (GetUnitNestingLevel(index) - startLevel).ToString(), GetUnitFunctionName(index), "0", GetUnitInclTime(index), " ", " ");
                index++;
            }
            WriteGibberishForOffView(m_sw);
            m_sw.WriteLine();
            m_sw.WriteLine("STATISTICS:");
            m_sw.WriteLine("Total Threads = 0");
            m_sw.WriteLine("Maximum Concurrent Threads = 1");
            m_sw.WriteLine("Total Function Nodes = {0}", (index - unit.NItem));
            m_sw.WriteLine("Total Function Calls = {0}", (index - unit.NItem));
            m_sw.WriteLine("Memory Buffer Used = 1K");
            m_sw.WriteLine("Memory Buffer Allocated = 1K");
            m_sw.WriteLine("Memory Buffer Reserved = 2K");
            m_sw.Flush();
            m_sw.Close();
        }
 public string GetUnitFunctionName(NativeProfilerUnit unit)
 {
     return (string)htFunctionNames[unit.FunctionAddress];
 }
        public NativeProfiler(Stream m_tInput, string mapFileName, bool b_checkBlockBegin)
        {
            bool needRestart = true;
            long streamLength = m_tInput.Length;
            uint nRestarts = 0;
            while (needRestart == true && streamLength > 0)
            {
                needRestart = false;
                try
                {              
                    NativeProfilerUnit[] htN_temp = new NativeProfilerUnit[streamLength];
                    htFunctionNames = new Hashtable();
                    htN = new NativeProfilerUnit[streamLength];
                    htInclTime = new uint[streamLength];
                    htExclTime = new uint[streamLength];
                    Stack stack = new Stack(8096);
                    byte[] bArray = new byte[20];
                    m_tInput.Seek(0, SeekOrigin.Begin);
                    nItems = 0;
                    totalRuntime = 0;
                    long n = 0;
                    uint level = 0;
                    uint address = 0, time = 0;
                    uint checkValue = 0;

                    NativeProfilerUnit unit;

                    if (b_checkBlockBegin == true)
                    {
                        while (streamLength - m_tInput.Position >= 4 && checkValue != 0xbaadf00d)
                        {
                            m_tInput.Read(bArray, 0, 4);
                            
                            checkValue = BitConverter.ToUInt32(bArray, 0);
                            if (checkValue != 0xbaadf00d)
                            {
                                m_tInput.Seek(-3, SeekOrigin.Current);
                            }
                            else
                            {
                                m_tInput.Read(bArray, 0, 4);
                                engineTimeOffset = BitConverter.ToUInt32(bArray, 0);
                            }
                        }
                    }
                    
                    while (streamLength - m_tInput.Position >= 8)
                    {
                        m_tInput.Read(bArray, 0, 8);
                        address = BitConverter.ToUInt32(bArray, 0);
                        time = BitConverter.ToUInt32(bArray, 4);
                        if (address != 0xbaadf00d && address != 0xd00fdaab && time != 0xbaadf00d && time != 0xd00fdaab)
                        {
                            if ((address & 1) == 0) // if the address is even then it is a push opcode
                            {
                                unit = new NativeProfilerUnit();
                                unit.EntryTime = time;
                                unit.FunctionAddress = address;
                                unit.NestingLevel = level;
                                unit.ReturnTime = 0xffffffff;
                                htN_temp[n] = unit;
                                stack.Push(unit);
                                n++;
                                level++;
                                // Adds a reference that a key for 'address' exists in htFunctionNames.
                                htFunctionNames[address] = null;
                            }
                            else if (stack.Count > 0) // if the address is odd then it is a pop opcode
                            {
                                unit = (NativeProfilerUnit)stack.Pop();
                                unit.ReturnTime = time;
                                level--;
                            }
                        }
                        else if (time == 0xbaadf00d)
                        {
                            if (m_tInput.Length - m_tInput.Position >= 4)
                            {
                                m_tInput.Seek(4, SeekOrigin.Current);
                            }
                        }
                        else if (address == 0xd00fdaab || time == 0xd00fdaab)
                        {
                            if (time != 0xbaadf00d)
                            {
                                m_tInput.Seek(-3, SeekOrigin.Current);
                            }
                            while (streamLength - m_tInput.Position >= 4 && time != 0xbaadf00d)
                            {
                                m_tInput.Read(bArray, 0, 4);
                                time = BitConverter.ToUInt32(bArray, 0);
                                if (time != 0xbaadf00d)
                                {
                                    m_tInput.Seek(-3, SeekOrigin.Current);
                                }
                            }
                            m_tInput.Read(bArray, 0, 4);
                            
                        }
                    }

                    OpenMAPFile(mapFileName);
                    totalRuntime = 0;

                    // Do some simple data consistancy check
                    // We use time, and check that the level of the next unit - level of the previous level is <= 1;
                    uint index = 0;
                    unit = (NativeProfilerUnit)htN_temp[index];
                    minimalLevel = 0xffffffff;
                    while (unit != null)
                    {
                        if (unit.ReturnTime > unit.EntryTime && unit.ReturnTime != 0xffffffff &&
                            unit.EntryTime != 0xffffffff && htFunctionNames[unit.FunctionAddress] != null &&
                            (nItems == 0 || nItems != 0 && ((int)unit.NestingLevel - (int)htN[nItems - 1].NestingLevel <= 1)))
                        {
                            htN[nItems] = unit;
                            unit.NItem = nItems;
                            nItems++;
                            if (unit.NestingLevel < minimalLevel) minimalLevel = unit.NestingLevel;
                        }
                        else
                        {
                            if (nItems != 0)
                            {
                                // If the node after the last one is not correct then destroy the last node too.
                                htN[nItems - 1] = null;
                                nItems--;
                            }
                            break;
                        }
                        index++;
                        unit = (NativeProfilerUnit)htN_temp[index];
                    }
                    if (minimalLevel == 0xffffffff) minimalLevel = 0;


                    // The last nodes seems to be scratched sometimes.
                    // So we ignore everything from the node after the last one until the node of level minimalLevel,
                    // or the node which is null (if it is not already that one).
                    NativeProfilerUnit lastNode;
                    uint lastLevel = minimalLevel;
                    index = nItems;
                    do
                    {
                        lastNode = (NativeProfilerUnit)htN[index];
                        if (lastNode != null) lastLevel = lastNode.NestingLevel;
                        index--;
                    }
                    while (lastNode != null && lastLevel > minimalLevel);
                    if (index != nItems - 1) lastNode = (NativeProfilerUnit)htN[index];

                    unit = (NativeProfilerUnit)htN[(uint)0];

                    index = 0;
                    while (unit != null && unit != lastNode)
                    {
                        index++;
                        unit = (NativeProfilerUnit)htN[index];
                    }

                    nItems = index;
                    htN[nItems] = null;

                    // Count inclusive, exclusive time
                    for (index = 0; index < nItems; index++)
                    {
                        unit = GetUnit(index);
                        uint entryTime = unit.EntryTime;
                        uint returnTime = unit.ReturnTime;
                        level = unit.NestingLevel;
                        uint count = index + 1;
                        long exclTime = (long)unit.ExecutionTime - (long)EngineTimeOffset;
                        while (count < nItems && htN[count] != null && ((NativeProfilerUnit)htN[count]).ReturnTime < returnTime && ((NativeProfilerUnit)htN[count]).EntryTime < returnTime)
                        {
                            if (((NativeProfilerUnit)htN[count]).NestingLevel == level + 1)
                            {
                                exclTime = exclTime - ((NativeProfilerUnit)htN[count]).ExecutionTime;
                            }
                            count++;
                        }

                        if (exclTime < 0) exclTime = 0;
                        htExclTime[index] = (uint)exclTime;
                    }

                    for (index = nItems - 1; (int)index >= 0; index--)
                    {
                        unit = GetUnit(index);
                        uint entryTime = unit.EntryTime;
                        uint returnTime = unit.ReturnTime;
                        level = unit.NestingLevel;
                        uint count = index + 1;
                        long inclTime = 0;
                        while (count < nItems && htN[count] != null && ((NativeProfilerUnit)htN[count]).ReturnTime < returnTime && ((NativeProfilerUnit)htN[count]).EntryTime < returnTime)
                        {
                            if (((NativeProfilerUnit)htN[count]).NestingLevel == level + 1)
                            {
                                inclTime = inclTime + htInclTime[count];
                            }
                            count++;
                        }

                        inclTime += htExclTime[index];
                        htInclTime[index] = (uint)(inclTime);
                        if (unit.NestingLevel == minimalLevel) totalRuntime += (uint)inclTime;
                    }
                }
                catch (System.OutOfMemoryException)
                {
                    if(nRestarts == 0) System.Windows.Forms.MessageBox.Show("Out of memory. Will try to strip data until load of data is possible.");
                    needRestart = true;
                    streamLength /= 2;
                    nRestarts++;
                }
                catch (Exception e)
                {
                    System.Windows.Forms.MessageBox.Show("Unfortunately there was an error during decoding data. Exception sent: " + e.ToString());
                }
            }
        }