1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
//----------------------------------------------------------
// MethodContextReader.h - Abstraction for reading MethodContexts
// Should eventually support multithreading
//----------------------------------------------------------
#ifndef _MethodContextReader
#define _MethodContextReader
#include "methodcontext.h"
#include "tocfile.h"
struct MethodContextBuffer
{
private:
static const int Completed = 0x1234abcd;
public:
unsigned char* buff;
DWORD size;
MethodContextBuffer() : buff(nullptr), size(Completed)
{
}
MethodContextBuffer(DWORD error) : buff(nullptr), size(error)
{
}
MethodContextBuffer(unsigned char* b, DWORD e) : buff(b), size(e)
{
}
bool allDone()
{
return size == Completed && buff == nullptr;
}
bool Error()
{
return size != 0 && size != Completed && buff == nullptr;
}
};
// The pack(4) directive is so that each entry is 12 bytes, intead of 16
#pragma pack(push)
#pragma pack(4)
class MethodContextReader
{
private:
// The MC/MCH file
HANDLE fileHandle;
// The size of the MC/MCH file
__int64 fileSize;
// Current MC index in the input MC/MCH file
int curMCIndex;
// The synchronization mutex
HANDLE mutex;
bool AcquireLock();
void ReleaseLock();
TOCFile tocFile;
// Method ranges to process
// If you have an index file, these things get processed
// much faster, now
const int* Indexes;
int IndexCount;
int curIndexPos;
// Method hash to process
// If you have an index file, these things get processed
// much faster, now
char* Hash;
int curTOCIndex;
// Offset/increment if running in parallel mode
// If you have an index file, these things get processed
// much faster, now
int Offset;
int Increment;
// Binary search to get this method number from the index
// Returns -1 for not found, or -2 for not indexed
__int64 GetOffset(unsigned int methodNumber);
// Just a helper...
static HANDLE OpenFile(const char* inputFile, DWORD flags = FILE_ATTRIBUTE_NORMAL);
MethodContextBuffer ReadMethodContextNoLock(bool justSkip = false);
MethodContextBuffer ReadMethodContext(bool acquireLock, bool justSkip = false);
MethodContextBuffer GetSpecificMethodContext(unsigned int methodNumber);
MethodContextBuffer GetNextMethodContextFromIndexes();
MethodContextBuffer GetNextMethodContextFromHash();
MethodContextBuffer GetNextMethodContextFromOffsetIncrement();
MethodContextBuffer GetNextMethodContextHelper();
// Looks for a file named foo.origSuffix.newSuffix or foo.newSuffix
// but only if foo.origSuffix exists
static std::string CheckForPairedFile(const std::string& fileName,
const std::string& origSuffix,
const std::string& newSuffix);
// are we're at the end of the file...
bool atEof();
// Do we have a valid TOC?
bool hasTOC();
// Do we have a valid index?
bool hasIndex();
public:
MethodContextReader(const char* inputFileName,
const int* indexes = nullptr,
int indexCount = -1,
char* hash = nullptr,
int offset = -1,
int increment = -1);
~MethodContextReader();
// Read a method context buffer from the ContextCollection
// (either a hive [single] or an index)
MethodContextBuffer GetNextMethodContext();
// No C++ exceptions, so the constructor has to always succeed...
bool isValid();
double PercentComplete();
// Returns the index of the last MethodContext read by GetNextMethodContext
inline int GetMethodContextIndex()
{
return curMCIndex;
}
};
#pragma pack(pop)
#endif
|