1 | // |
2 | // Copyright (c) Microsoft. All rights reserved. |
3 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
4 | // |
5 | |
6 | #include "standardpch.h" |
7 | #include "methodcontext.h" |
8 | #include "methodcontextiterator.h" |
9 | |
10 | bool MethodContextIterator::Initialize(const char* fileName) |
11 | { |
12 | m_hFile = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, |
13 | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); |
14 | if (m_hFile == INVALID_HANDLE_VALUE) |
15 | { |
16 | LogError("Failed to open file '%s'. GetLastError()=%u" , fileName, GetLastError()); |
17 | return false; |
18 | } |
19 | |
20 | LARGE_INTEGER DataTemp; |
21 | if (GetFileSizeEx(m_hFile, &DataTemp) == 0) |
22 | { |
23 | LogError("GetFileSizeEx failed. GetLastError()=%u" , GetLastError()); |
24 | CloseHandle(m_hFile); |
25 | m_hFile = INVALID_HANDLE_VALUE; |
26 | return false; |
27 | } |
28 | |
29 | m_fileSize = DataTemp.QuadPart; |
30 | |
31 | if (m_progressReport) |
32 | { |
33 | m_timer->Start(); |
34 | } |
35 | |
36 | return true; |
37 | } |
38 | |
39 | bool MethodContextIterator::Destroy() |
40 | { |
41 | bool ret = true; // assume success |
42 | if (m_hFile != INVALID_HANDLE_VALUE) |
43 | { |
44 | if (!CloseHandle(m_hFile)) |
45 | { |
46 | LogError("CloseHandle failed. GetLastError()=%u" , GetLastError()); |
47 | ret = false; |
48 | } |
49 | m_hFile = INVALID_HANDLE_VALUE; |
50 | } |
51 | delete m_mc; |
52 | m_mc = nullptr; |
53 | |
54 | if (m_index < m_indexCount) |
55 | { |
56 | LogWarning("Didn't use all of index count input: %d < %d (i.e., didn't see MC #%d)" , m_index, m_indexCount, |
57 | m_indexes[m_index]); |
58 | } |
59 | |
60 | delete m_timer; |
61 | m_timer = nullptr; |
62 | |
63 | return ret; |
64 | } |
65 | |
66 | bool MethodContextIterator::MoveNext() |
67 | { |
68 | if (m_mc != nullptr) |
69 | { |
70 | delete m_mc; |
71 | m_mc = nullptr; |
72 | } |
73 | |
74 | while (true) |
75 | { |
76 | // Figure out where the pointer is currently. |
77 | LARGE_INTEGER pos; |
78 | pos.QuadPart = 0; |
79 | if (SetFilePointerEx(m_hFile, pos, &m_pos, FILE_CURRENT) == 0) |
80 | { |
81 | LogError("SetFilePointerEx failed. GetLastError()=%u" , GetLastError()); |
82 | return false; // any failure causes us to bail out. |
83 | } |
84 | |
85 | if (m_pos.QuadPart >= m_fileSize) |
86 | { |
87 | return false; |
88 | } |
89 | |
90 | // Load the current method context. |
91 | m_methodContextNumber++; |
92 | |
93 | if (m_progressReport) |
94 | { |
95 | if (m_methodContextNumber % 500 == 0) |
96 | { |
97 | m_timer->Stop(); |
98 | LogVerbose("Loaded %d at %d per second" , m_methodContextNumber, |
99 | (int)((double)500 / m_timer->GetSeconds())); |
100 | m_timer->Start(); |
101 | } |
102 | } |
103 | |
104 | if (!MethodContext::Initialize(m_methodContextNumber, m_hFile, &m_mc)) |
105 | return false; |
106 | |
107 | // If we have an array of indexes, skip the loaded indexes that have not been specified. |
108 | |
109 | if (m_indexCount == -1) |
110 | { |
111 | break; |
112 | } |
113 | else if (m_index == m_indexCount) |
114 | { |
115 | return false; // we're beyond the array of indexes |
116 | } |
117 | else if (m_index < m_indexCount) |
118 | { |
119 | if (m_indexes[m_index] == m_methodContextNumber) |
120 | { |
121 | m_index++; |
122 | break; |
123 | } |
124 | } |
125 | } |
126 | |
127 | return true; |
128 | } |
129 | |