diff options
Diffstat (limited to 'src/ToolBox/superpmi/superpmi-shared/methodcontextiterator.cpp')
-rw-r--r-- | src/ToolBox/superpmi/superpmi-shared/methodcontextiterator.cpp | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontextiterator.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontextiterator.cpp new file mode 100644 index 0000000000..55f8045938 --- /dev/null +++ b/src/ToolBox/superpmi/superpmi-shared/methodcontextiterator.cpp @@ -0,0 +1,127 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +#include "standardpch.h" +#include "methodcontext.h" +#include "methodcontextiterator.h" + + +bool MethodContextIterator::Initialize(const char* fileName) +{ + m_hFile = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (m_hFile == INVALID_HANDLE_VALUE) + { + LogError("Failed to open file '%s'. GetLastError()=%u", fileName, GetLastError()); + return false; + } + + LARGE_INTEGER DataTemp; + if (GetFileSizeEx(m_hFile, &DataTemp)==0) + { + LogError("GetFileSizeEx failed. GetLastError()=%u", GetLastError()); + CloseHandle(m_hFile); + m_hFile = INVALID_HANDLE_VALUE; + return false; + } + + m_fileSize = DataTemp.QuadPart; + + if (m_progressReport) + { + m_timer->Start(); + } + + return true; +} + +bool MethodContextIterator::Destroy() +{ + bool ret = true; // assume success + if (m_hFile != INVALID_HANDLE_VALUE) + { + if (!CloseHandle(m_hFile)) + { + LogError("CloseHandle failed. GetLastError()=%u", GetLastError()); + ret = false; + } + m_hFile = INVALID_HANDLE_VALUE; + } + delete m_mc; + m_mc = nullptr; + + if (m_index < m_indexCount) + { + LogWarning("Didn't use all of index count input: %d < %d (i.e., didn't see MC #%d)", + m_index, m_indexCount, m_indexes[m_index]); + } + + delete m_timer; + m_timer = nullptr; + + return ret; +} + +bool MethodContextIterator::MoveNext() +{ + if (m_mc != nullptr) + { + delete m_mc; + m_mc = nullptr; + } + + while (true) + { + // Figure out where the pointer is currently. + LARGE_INTEGER pos; + pos.QuadPart = 0; + if (SetFilePointerEx(m_hFile, pos, &m_pos, FILE_CURRENT) == 0) + { + LogError("SetFilePointerEx failed. GetLastError()=%u", GetLastError()); + return false; // any failure causes us to bail out. + } + + if (m_pos.QuadPart >= m_fileSize) + { + return false; + } + + // Load the current method context. + m_methodContextNumber++; + + if (m_progressReport) + { + if (m_methodContextNumber % 500 == 0) + { + m_timer->Stop(); + LogVerbose("Loaded %d at %d per second", m_methodContextNumber, (int)((double)500 / m_timer->GetSeconds())); + m_timer->Start(); + } + } + + if (!MethodContext::Initialize(m_methodContextNumber, m_hFile, &m_mc)) + return false; + + // If we have an array of indexes, skip the loaded indexes that have not been specified. + + if (m_indexCount == -1) + { + break; + } + else if (m_index == m_indexCount) + { + return false; // we're beyond the array of indexes + } + else if (m_index < m_indexCount) + { + if (m_indexes[m_index] == m_methodContextNumber) + { + m_index++; + break; + } + } + } + + return true; +} |