1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | |
6 | #ifndef _MDA_ |
7 | #define _MDA_ |
8 | |
9 | #ifndef _DEBUG |
10 | #ifdef DACCESS_COMPILE |
11 | #undef MDA_SUPPORTED |
12 | #endif |
13 | #endif |
14 | |
15 | #ifdef MDA_SUPPORTED |
16 | |
17 | #include "sarray.h" |
18 | #include "eeconfig.h" |
19 | // Factory includes |
20 | #include <xmlparser.h> |
21 | #include <objbase.h> |
22 | #include "unknwn.h" |
23 | #include "crst.h" |
24 | #include "../xmlparser/_reference.h" |
25 | #include "../dlls/mscorrc/resource.h" |
26 | |
27 | #define MdaTypeOf(TYPE) ((TYPE*)0) |
28 | #define MdaType(TYPE) (TYPE*) |
29 | #define MdaElemDecl(NAME) MdaElemDecl##NAME |
30 | #define MdaElemDef(NAME) MdaElemDef##NAME |
31 | #define MdaAttrDecl(NAME) MdaAttrDecl##NAME |
32 | |
33 | #define MDA_TARGET_NAMESPACE W("http://schemas.microsoft.com/CLR/2004/10/mda") |
34 | #define MDA_SCHEMA_PREFIX W("mda") |
35 | |
36 | |
37 | class ManagedDebuggingAssistants; |
38 | class MdaAssistant; |
39 | class MdaInvalidConfigFile; |
40 | class MdaXmlElement; |
41 | class MdaXmlAttribute; |
42 | class MdaXmlMessage; |
43 | class MdaXmlIndustry; |
44 | class MdaXPath; |
45 | class MdaSchema; |
46 | class MdaSchemaSchema; |
47 | class MdaAssistantSchema; |
48 | class MdaAssistantMsgSchema; |
49 | class MdaXmlValidationError; |
50 | class MdaFramework; |
51 | template<typename> class MdaFactory; |
52 | |
53 | #define MDA_BUFFER_SIZE 256 |
54 | #define MDA_XML_NAME_SIZE 16 |
55 | #define MDA_XML_VALUE_SIZE 16 |
56 | #define MDA_XML_ELEMENT_CHILDREN 16 |
57 | #define MDA_XML_ELEMENT_ATTRIBUTES 16 |
58 | #define MDA_MAX_FACTORY_PRODUCT 20 |
59 | #define MDA_MAX_STACK_ELEMENTS 20 |
60 | #define MDA_MAX_STACK_ATTRIBUTES 20 |
61 | |
62 | typedef enum |
63 | { |
64 | MdaSchemaPrimitiveBOOL, |
65 | MdaSchemaPrimitiveSString, |
66 | MdaSchemaPrimitiveINT32, |
67 | MdaSchemaPrimitiveUnknown, |
68 | } MdaSchemaPrimitive; |
69 | |
70 | // HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PoolTag |
71 | // Hex\Text value |
72 | |
73 | // HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PoolTagOverruns |
74 | // 0x0 == Verify Start, 0x1 == VerifyEnd |
75 | |
76 | #define GFLAG_REG_KEY_PATH W("SYSTEM\\CurrentControlSet\\Control\\Session Manager") |
77 | #define GFLAG_REG_KEY_NAME W("GlobalFlag") |
78 | #define MDA_REG_KEY_PATH FRAMEWORK_REGISTRY_KEY_W |
79 | #define MDA_REG_KEY_ENABLE W("MdaEnable") |
80 | #define MDA_CONFIG_ENV_VARIABLE W("MDA_CONFIG") |
81 | |
82 | extern const bool g_mdaAssistantIsSwitch[]; |
83 | |
84 | typedef enum : BYTE |
85 | { |
86 | #define MDA_DEFINE_ASSISTANT_ENUMERATION |
87 | #include "mdaschema.inl" |
88 | #undef MDA_DEFINE_ASSISTANT_ENUMERATION |
89 | MdaElemDef(AssistantMax), |
90 | |
91 | #define MDA_ELEMENT_DEFINITION_ENUMERATION |
92 | #include "mdaschema.inl" |
93 | #undef MDA_ELEMENT_DEFINITION_ENUMERATION |
94 | MdaElemDef(Max), |
95 | |
96 | #define MDA_ELEMENT_DECLARAION_ENUMERATION |
97 | #include "mdaschema.inl" |
98 | #undef MDA_ELEMENT_DECLARAION_ENUMERATION |
99 | MdaElemDecl(Max), |
100 | MdaElemComment, |
101 | MdaElemUndefined, |
102 | MdaElemEnd, |
103 | } MdaElemDeclDef; |
104 | |
105 | typedef enum |
106 | { |
107 | #define MDA_ATTRIBUTE_DECLARATION_ENUMERATION |
108 | #include "mdaschema.inl" |
109 | #undef MDA_ATTRIBUTE_DECLARATION_ENUMERATION |
110 | MdaAttrDecl(Max), |
111 | |
112 | MdaAttrUndefined, |
113 | MdaAttrEnd, |
114 | } MdaAttrDeclDef; |
115 | |
116 | typedef const SString CSString; |
117 | |
118 | #pragma warning(push) |
119 | #pragma warning(disable:4324) |
120 | |
121 | // |
122 | // MdaStack |
123 | // |
124 | template<typename TYPE> |
125 | class MdaStack |
126 | { |
127 | private: // MdaStack not for general use. // |
128 | MdaStack() : m_depth(0) { LIMITED_METHOD_CONTRACT; } |
129 | |
130 | public: // MdaStack not for general use. // |
131 | void Set(MdaStack<TYPE>* pStack) { WRAPPER_NO_CONTRACT; m_stack.Set(pStack->m_stack); m_depth = pStack->m_depth; } |
132 | TYPE Push(TYPE element) { WRAPPER_NO_CONTRACT; *m_stack.Append() = element; m_depth++; return Tos(); } |
133 | TYPE Push() { WRAPPER_NO_CONTRACT; *m_stack.Append(); m_depth++; return Tos(); } |
134 | TYPE Pop() { WRAPPER_NO_CONTRACT; PRECONDITION(GetDepth() > 0); TYPE tos = Tos(); m_stack.Delete(m_stack.End() - 1); m_depth--; return tos; } |
135 | TYPE Tos() { WRAPPER_NO_CONTRACT; return m_stack.End()[-1]; } |
136 | void Clear() { WRAPPER_NO_CONTRACT; while(GetDepth()) Pop(); } |
137 | COUNT_T GetDepth() { WRAPPER_NO_CONTRACT; return m_depth; } |
138 | |
139 | private: |
140 | friend class MdaConfigFactory; |
141 | friend class ManagedDebuggingAssistants; |
142 | friend class MdaSchema; |
143 | friend class MdaXPath; |
144 | |
145 | private: |
146 | INT32 m_depth; |
147 | InlineSArray<TYPE, 16> m_stack; |
148 | }; |
149 | |
150 | |
151 | // |
152 | // MdaHashtable |
153 | // |
154 | BOOL MdaLockOwner(LPVOID); |
155 | |
156 | template<typename TYPE> |
157 | class MdaHashtable |
158 | { |
159 | private: // MdaHashtable not for general use. // |
160 | MdaHashtable() { WRAPPER_NO_CONTRACT; LockOwner lockOwner = {NULL, MdaLockOwner}; m_ht.Init(11, &lockOwner); } |
161 | |
162 | public: // MdaHashtable not for general use. // |
163 | TYPE Get(LPCWSTR pKey) { WRAPPER_NO_CONTRACT; StackSString sKey(pKey); return Get(&sKey); } |
164 | BOOL Get(LPCWSTR pKey, TYPE* pValue) { WRAPPER_NO_CONTRACT; StackSString sKey(pKey); return Get(&sKey, pValue); } |
165 | BOOL HasKey(LPCWSTR pKey) { TYPE value; return Get(pKey, &value); } |
166 | TYPE Get(CSString* pKey) |
167 | { |
168 | WRAPPER_NO_CONTRACT; |
169 | TYPE value; |
170 | ASSERT(Get(pKey, &value)); |
171 | return value; |
172 | } |
173 | BOOL Get(CSString* psszKey, TYPE* pValue) |
174 | { |
175 | WRAPPER_NO_CONTRACT; |
176 | EEStringData key(psszKey->GetCount(), psszKey->GetUnicode()); |
177 | HashDatum value; |
178 | if (m_ht.GetValue(&key, &value)) |
179 | { |
180 | *pValue = (TYPE)(UINT_PTR)value; |
181 | return TRUE; |
182 | } |
183 | return FALSE; |
184 | } |
185 | void EmptyHashTable() { WRAPPER_NO_CONTRACT; m_ht.EmptyHashTable(); } |
186 | void DeleteValue(LPCWSTR szKey) |
187 | { |
188 | WRAPPER_NO_CONTRACT; |
189 | StackSString sszKey(szKey); |
190 | EEStringData key(sszKey.GetCount(), sszKey.GetUnicode()); |
191 | m_ht.DeleteValue(&key); |
192 | } |
193 | DWORD GetCount() { WRAPPER_NO_CONTRACT; return m_ht.GetCount(); } |
194 | |
195 | TYPE Set(LPCWSTR pKey, TYPE value) { WRAPPER_NO_CONTRACT; StackSString sszKey(pKey); return Set(&sszKey, value); } |
196 | TYPE Set(CSString* psszKey, TYPE value) |
197 | { |
198 | WRAPPER_NO_CONTRACT; |
199 | EEStringData key(psszKey->GetCount(), psszKey->GetUnicode()); |
200 | m_ht.InsertValue(&key, (HashDatum)value); |
201 | return value; |
202 | } |
203 | |
204 | private: |
205 | friend class MdaXmlElement; |
206 | friend class MdaSchema; |
207 | friend class ManagedDebuggingAssistants; |
208 | |
209 | private: |
210 | EEUnicodeStringHashTable m_ht; |
211 | }; |
212 | |
213 | |
214 | // |
215 | |
216 | // MdaEnvironment |
217 | // |
218 | class MdaEnvironment |
219 | { |
220 | public: |
221 | MdaEnvironment(); |
222 | ~MdaEnvironment(); |
223 | BOOL IsDisabled() { return m_bDisable; } |
224 | LPCWSTR GetConfigFile() { return m_psszConfigFile->GetUnicode(); } |
225 | LPCWSTR GetMdaConfigFile() { return m_psszMdaConfigFile->GetUnicode(); } |
226 | SArray<SString*>& GetActivationMechanisms() { return *m_pGroups; } |
227 | |
228 | private: |
229 | LPWSTR m_szMda; |
230 | MdaFactory<StackSString>* m_pStringFactory; |
231 | SString* m_psszMdaConfigFile; |
232 | SString* m_psszConfigFile; |
233 | BOOL m_bDisable; |
234 | SArray<SString*>* m_pGroups; |
235 | }; |
236 | |
237 | |
238 | // |
239 | // Mda |
240 | // |
241 | |
242 | // Use these macros if your callsite cannot run on the debugger helper thread. This is the fastest version. |
243 | #define MDA_GET_ASSISTANT(ASSISTANT) (Mda##ASSISTANT*)ManagedDebuggingAssistants::GetAssistant(MdaElemDef(ASSISTANT)) |
244 | #define MDA_TRIGGER_ASSISTANT(ASSISTANT, MEMBER) if (Mda##ASSISTANT* pMdaAssistant = MDA_GET_ASSISTANT(ASSISTANT)) pMdaAssistant->MEMBER |
245 | |
246 | // Use these macros if your callsite might run on the debugger helper thread. This should be avoided for |
247 | // very hot checks. |
248 | #define MDA_GET_ASSISTANT_EX(ASSISTANT) (Mda##ASSISTANT*)ManagedDebuggingAssistants::GetAssistantEx(MdaElemDef(ASSISTANT)) |
249 | #define MDA_TRIGGER_ASSISTANT_EX(ASSISTANT, MEMBER) if (Mda##ASSISTANT* pMdaAssistant = MDA_GET_ASSISTANT_EX(ASSISTANT)) pMdaAssistant->MEMBER |
250 | |
251 | class ManagedDebuggingAssistants |
252 | { |
253 | public: |
254 | FORCEINLINE static MdaAssistant* GetAssistant(MdaElemDeclDef id); |
255 | FORCEINLINE static MdaAssistant* GetAssistantEx(MdaElemDeclDef id); |
256 | FORCEINLINE static void Enable(MdaElemDeclDef assistantDeclDef, MdaAssistant* pMda); |
257 | |
258 | private: |
259 | static void AllocateManagedDebuggingAssistants(); |
260 | ManagedDebuggingAssistants(); |
261 | void Initialize(); |
262 | #ifdef _DEBUG |
263 | void DebugInitialize(); |
264 | #endif |
265 | |
266 | private: |
267 | void SetFwLink(MdaElemDeclDef assistant, LPCWSTR szFwLink) { LIMITED_METHOD_CONTRACT; m_szFwLinks[assistant] = szFwLink; } |
268 | LPCWSTR GetFwLink(MdaElemDeclDef assistant) { LIMITED_METHOD_CONTRACT; return m_szFwLinks[assistant]; } |
269 | void ReadAppConfigurationFile(MdaXmlElement* pXmlRoot, SString* pConfigFile, MdaStack<LPCWSTR>* pConfigMdaRoot); |
270 | MdaXmlElement* GetRootElement(MdaXmlElement* pMdaXmlRoot); |
271 | void EnvironmentActivation(MdaEnvironment* pEnvironment); |
272 | void ConfigFileActivation(LPCWSTR szConfigFile, MdaXmlIndustry* pXmlIndustry, MdaHashtable<MdaXmlElement*>* pXmlConfigs); |
273 | void ActivateGroup(LPCWSTR groupName, SArray<MdaElemDeclDef>* pGroup, MdaHashtable<MdaXmlElement*>* pXmlConfigs); |
274 | MdaXmlElement* GetSwitchActivationXml(MdaElemDeclDef mda); |
275 | |
276 | public: |
277 | static BOOL IsDebuggerAttached(); |
278 | static BOOL IsManagedDebuggerAttached(); |
279 | static BOOL IsUnmanagedDebuggerAttached(); |
280 | |
281 | private: |
282 | static void EEStartupActivation(); |
283 | |
284 | private: |
285 | friend HRESULT EEStartup(DWORD fFlags); |
286 | |
287 | private: |
288 | friend class MdaAssistant; |
289 | friend class MdaEnvironment; |
290 | friend class MdaInvalidConfigFile; |
291 | friend class MdaSchema; |
292 | friend class MdaAssistantSchema; |
293 | friend class MdaAssistantMsgSchema; |
294 | friend class MdaSchemaSchema; |
295 | friend class MdaXmlMessage; |
296 | friend class MdaXmlIndustry; |
297 | friend class MdaConfigFactory; |
298 | friend class MdaFramework; |
299 | friend void EEStartupHelper(COINITIEE fFlags); |
300 | |
301 | private: |
302 | BOOL GetConfigBool(MdaAttrDeclDef attrDeclDef, MdaElemDeclDef element = MdaElemUndefined, BOOL bDefault = FALSE); |
303 | BOOL GetConfigBool(MdaAttrDeclDef attrDeclDef, BOOL bDefault) { WRAPPER_NO_CONTRACT; return GetConfigBool(attrDeclDef, MdaElemUndefined, bDefault); } |
304 | |
305 | private: |
306 | Crst* m_pLock; |
307 | BOOL m_bValidateOutput, m_bIsInitialized; |
308 | LPCWSTR m_szFwLinks[MdaElemDef(AssistantMax)]; |
309 | MdaSchema* m_pAssistantSchema; |
310 | MdaSchema* m_pAssistantMsgSchema; |
311 | MdaSchema* m_pSchemaSchema; |
312 | MdaXmlIndustry* m_pMdaXmlIndustry; |
313 | MdaXmlElement* m_pSwitchActivationXml; |
314 | }; |
315 | |
316 | |
317 | |
318 | typedef VPTR(MdaAssistant) PTR_MdaAssistant; |
319 | |
320 | // |
321 | // MdaAssistant |
322 | // |
323 | class MdaAssistant |
324 | { |
325 | friend class ValidateMdaAssistantLayout; |
326 | public: |
327 | static MdaXmlElement* OutputThread(Thread* pThread, MdaXmlElement* pXml); |
328 | static MdaXmlElement* OutputParameter(SString parameterName, USHORT sequence, MethodDesc* pMethodDesc, MdaXmlElement* pXml); |
329 | static MdaXmlElement* OutputMethodTable(MethodTable* pMT, MdaXmlElement* pXml); |
330 | static MdaXmlElement* OutputMethodDesc(MethodDesc* pMethodDesc, MdaXmlElement* pXml); |
331 | static MdaXmlElement* OutputFieldDesc(FieldDesc* pFieldDesc, MdaXmlElement* pXml); |
332 | static MdaXmlElement* OutputTypeHandle(TypeHandle typeHandle, MdaXmlElement* pXml); |
333 | static MdaXmlElement* OutputModule(Module* pModule, MdaXmlElement* pXml); |
334 | static MdaXmlElement* OutputCallsite(MethodDesc *pMethodDesc, DWORD dwOffset, MdaXmlElement* pXml); |
335 | static MdaXmlElement* OutputException(OBJECTREF *pExceptionObj, MdaXmlElement* pXml); |
336 | |
337 | public: |
338 | static SString& ToString(SString& sszBuffer, Module* pModule); |
339 | static SString& ToString(SString& sszBuffer, TypeHandle typeHandle); |
340 | static SString& ToString(SString& sszBuffer, MethodDesc* pMethodDesc); |
341 | static SString& ToString(SString& sszBuffer, FieldDesc* pFieldDesc); |
342 | static void ToString(TypeHandle typeHandle, SString* psszFullname, SString* psszNamespace); |
343 | |
344 | public: |
345 | LPCWSTR GetName(); |
346 | |
347 | private: |
348 | void Initialize(MdaXmlElement* pXmlInput); |
349 | static BOOL IsAssistantActive(MdaXmlElement* pXml); |
350 | |
351 | private: |
352 | bool GetSuppressDialog() { LIMITED_METHOD_CONTRACT; return m_bSuppressDialog; } |
353 | MdaElemDeclDef GetAssistantDeclDef() { LIMITED_METHOD_CONTRACT; return m_assistantDeclDef; } |
354 | MdaElemDeclDef GetAssistantMsgDeclDef() { LIMITED_METHOD_CONTRACT; return m_assistantMsgDeclDef; } |
355 | MdaXmlElement* GetRootElement(MdaXmlElement* pMdaXmlRoot, BOOL bBreak); |
356 | |
357 | private: |
358 | friend class ManagedDebuggingAssistants; |
359 | friend class MdaXmlMessage; |
360 | |
361 | private: |
362 | // WARNING: do not modify the field layout without also |
363 | // modifying the MDA_ASSISTANT_BASE_MEMBERS macro. |
364 | MdaElemDeclDef m_assistantDeclDef; |
365 | MdaElemDeclDef m_assistantMsgDeclDef; |
366 | bool m_bSuppressDialog; |
367 | }; |
368 | |
369 | // |
370 | // MdaXmlAttribute |
371 | // |
372 | class MdaXmlAttribute |
373 | { |
374 | public: |
375 | LPCWSTR GetName(); |
376 | LPCWSTR GetValue() { LIMITED_METHOD_CONTRACT; PRECONDITION(CheckPointer(this)); return m_value.GetUnicode(); } |
377 | LPCWSTR GetValueAsUnicode() { LIMITED_METHOD_CONTRACT; PRECONDITION(CheckPointer(this)); return GetValueAsCSString()->GetUnicode(); } |
378 | SString* GetValueAsCSString() { LIMITED_METHOD_CONTRACT; PRECONDITION(CheckPointer(this)); return &m_value; } |
379 | BOOL GetValueAsBool() { LIMITED_METHOD_CONTRACT; PRECONDITION(CheckPointer(this)); ASSERT(m_type == MdaSchemaPrimitiveBOOL); return m_bool; } |
380 | INT32 GetValueAsInt32() { LIMITED_METHOD_CONTRACT; PRECONDITION(CheckPointer(this)); ASSERT(m_type == MdaSchemaPrimitiveINT32); return m_int; } |
381 | MdaAttrDeclDef GetDeclDef() { LIMITED_METHOD_CONTRACT; PRECONDITION(CheckPointer(this)); return m_declDef; } |
382 | |
383 | private: |
384 | SString* ToXml(SString* xml); |
385 | |
386 | MdaXmlAttribute* Initialize(LPCWSTR szName, LPCWSTR szValue); |
387 | |
388 | MdaXmlAttribute* SetSString(LPCUTF8 szValue) { WRAPPER_NO_CONTRACT; m_type = MdaSchemaPrimitiveSString; m_value.SetUTF8(szValue); return this; } |
389 | MdaXmlAttribute* SetSString(LPCWSTR szValue) { WRAPPER_NO_CONTRACT; m_type = MdaSchemaPrimitiveSString; m_value.Set(szValue); return this; } |
390 | MdaXmlAttribute* SetDeclDef(MdaAttrDeclDef declDef) { WRAPPER_NO_CONTRACT; m_declDef = declDef; return this; } |
391 | MdaXmlAttribute* SetNs(LPCWSTR szNs) { WRAPPER_NO_CONTRACT; m_szNs.Set(szNs); return this; } |
392 | MdaXmlAttribute* SetINT32(INT32 value) { LIMITED_METHOD_CONTRACT; m_type = MdaSchemaPrimitiveINT32; m_int = value; return this; } |
393 | MdaXmlAttribute* SetBOOL(BOOL value) { LIMITED_METHOD_CONTRACT; m_type = MdaSchemaPrimitiveBOOL; m_bool = value; return this; } |
394 | |
395 | private: |
396 | friend class ManagedDebuggingAssistants; |
397 | friend class MdaConfigFactory; |
398 | friend class MdaSchemaSchema; |
399 | friend class MdaXmlElement; |
400 | friend class MdaSchema; |
401 | friend class MdaXmlMessage; |
402 | template<typename PRODUCT> friend class MdaFactory; |
403 | |
404 | private: |
405 | MdaAttrDeclDef m_declDef; |
406 | SString m_szName; |
407 | SString m_szNs; |
408 | MdaSchemaPrimitive m_type; |
409 | SString m_value; |
410 | BOOL m_bool; |
411 | INT32 m_int; |
412 | }; |
413 | |
414 | |
415 | // |
416 | // MdaXmlElement |
417 | // |
418 | class MdaXmlElement |
419 | { |
420 | public: /* inspection */ |
421 | LPCWSTR GetName(); |
422 | MdaElemDeclDef GetDeclDef() { LIMITED_METHOD_CONTRACT; return m_elemDeclDef; } |
423 | BOOL IsDefinition() { LIMITED_METHOD_CONTRACT; return m_elemDeclDef < MdaElemDef(Max); } |
424 | BOOL IsDeclaration() { LIMITED_METHOD_CONTRACT; return !IsDefinition(); } |
425 | SArray<MdaXmlElement*>& GetChildren() { LIMITED_METHOD_CONTRACT; return m_children; } |
426 | MdaXmlElement* GetChild(MdaElemDeclDef declDef); |
427 | SArray<MdaXmlAttribute*>& GetAttributes() { LIMITED_METHOD_CONTRACT; return m_attributes; } |
428 | MdaXmlAttribute* GetAttribute(MdaAttrDeclDef attrDeclDef); |
429 | BOOL GetAttributeValueAsBool(MdaAttrDeclDef attrDeclDef, BOOL bDefault); |
430 | BOOL GetAttributeValueAsBool(MdaAttrDeclDef attrDeclDef); |
431 | |
432 | public: /* creation */ |
433 | MdaXmlElement* SetDeclDef(MdaElemDeclDef elemDeclDef) { LIMITED_METHOD_CONTRACT; m_elemDeclDef = elemDeclDef; return this; } |
434 | MdaXmlElement* SetName(LPCWSTR name, BOOL bAssertDefined = TRUE); |
435 | MdaXmlElement* AddChild(LPCWSTR name, BOOL bAssertDefined = TRUE); |
436 | MdaXmlElement* AddChild(MdaElemDeclDef type); |
437 | void AddChildComment(LPCWSTR szComment) { WRAPPER_NO_CONTRACT; AddChild(MdaElemComment)->m_szName.Set(szComment); } |
438 | LPCWSTR DebugToString(SString* pBuffer); |
439 | |
440 | template<typename ATTRIBUTE_TYPE> |
441 | MdaXmlAttribute* AddAttributeSz(MdaAttrDeclDef declDef, ATTRIBUTE_TYPE szValue) { return AddAttribute(declDef)->SetSString(szValue); } |
442 | MdaXmlAttribute* AddAttributeInt(MdaAttrDeclDef declDef, INT32 value) { return AddAttribute(declDef)->SetINT32(value); } |
443 | MdaXmlAttribute* AddAttributeBool(MdaAttrDeclDef declDef, BOOL bValue) { return AddAttribute(declDef)->SetBOOL(bValue); } |
444 | |
445 | private: |
446 | MdaXmlElement() : m_elemDeclDef(MdaElemUndefined), m_defaultAttrIndex(-1) { WRAPPER_NO_CONTRACT; } |
447 | MdaXmlElement* AddChild(MdaXmlElement* pChild); |
448 | |
449 | MdaXmlElement* SetIndustry(MdaXmlIndustry* pXmlIndustry) |
450 | { LIMITED_METHOD_CONTRACT; PRECONDITION(CheckPointer(pXmlIndustry, NULL_OK)); m_pXmlIndustry = pXmlIndustry; return this; } |
451 | |
452 | MdaXmlAttribute* AddDefaultAttribute(MdaAttrDeclDef attrDeclDef, LPCWSTR szValue); |
453 | MdaXmlAttribute* AddAttribute(LPCWSTR szName, LPCWSTR szValue); |
454 | |
455 | SString* ToXml(SString* xml) { WRAPPER_NO_CONTRACT; return ToXml(xml, NULL, 0); } |
456 | SString* ToXml(SString* xml, LPCWSTR ns) { WRAPPER_NO_CONTRACT; return ToXml(xml, ns, 0); } |
457 | SString* ToXml(SString* xml, LPCWSTR ns, INT32 depth); |
458 | |
459 | MdaXmlAttribute* AddAttribute(MdaAttrDeclDef declDef); |
460 | MdaXmlAttribute* AddAttribute(MdaXmlAttribute* pAttr) { WRAPPER_NO_CONTRACT; *m_attributes.Append() = pAttr; return pAttr; } |
461 | |
462 | private: |
463 | friend class MdaSchema; |
464 | friend class ManagedDebuggingAssistants; |
465 | friend class MdaXmlMessage; |
466 | friend class MdaXmlElement; |
467 | template<typename PRODUCT> friend class MdaFactory; |
468 | friend class MdaXmlIndustry; |
469 | friend class MdaConfigFactory; |
470 | friend class MdaSchemaSchema; |
471 | friend class MdaXmlValidationError; |
472 | |
473 | private: |
474 | MdaXmlIndustry* m_pXmlIndustry; |
475 | MdaElemDeclDef m_elemDeclDef; |
476 | SString m_szName; |
477 | InlineSArray<MdaXmlElement*, MDA_XML_ELEMENT_CHILDREN> m_children; |
478 | COUNT_T m_defaultAttrIndex; |
479 | InlineSArray<MdaXmlAttribute*, MDA_XML_ELEMENT_ATTRIBUTES> m_attributes; |
480 | }; |
481 | |
482 | |
483 | // |
484 | // MdaFactory |
485 | // |
486 | template<typename PRODUCT> |
487 | class MdaFactory |
488 | { |
489 | public: |
490 | MdaFactory() : m_cProduct(0), m_next(NULL) { LIMITED_METHOD_CONTRACT; } |
491 | ~MdaFactory() { LIMITED_METHOD_CONTRACT; if (m_next) delete m_next; } |
492 | MdaFactory* GetNext() { if (!m_next) m_next = new MdaFactory<PRODUCT>(); return m_next; } |
493 | PRODUCT* Create(); |
494 | |
495 | private: |
496 | MdaFactory* m_next; |
497 | PRODUCT m_product[MDA_MAX_FACTORY_PRODUCT]; |
498 | INT32 m_cProduct; |
499 | }; |
500 | |
501 | |
502 | // |
503 | // MdaXmlIndustry |
504 | // |
505 | class MdaXmlIndustry |
506 | { |
507 | public: |
508 | MdaXmlElement* CreateElement() { WRAPPER_NO_CONTRACT; return m_elements.Create()->SetIndustry(this); } |
509 | MdaXmlAttribute* CreateAttribute() { WRAPPER_NO_CONTRACT; return m_attributes.Create(); } |
510 | |
511 | private: |
512 | MdaFactory<MdaXmlElement> m_elements; |
513 | MdaFactory<MdaXmlAttribute> m_attributes; |
514 | |
515 | private: |
516 | friend class MdaConfigFactory; |
517 | friend class MdaFramework; |
518 | friend class MdaXmlMessage; |
519 | friend class ManagedDebuggingAssistants; |
520 | friend class MdaXmlElement; |
521 | friend class MdaXmlAttribute; |
522 | friend class MdaSchema; |
523 | }; |
524 | |
525 | |
526 | // |
527 | // MdaXmlMessage |
528 | // |
529 | class MdaXmlMessage |
530 | { |
531 | public: |
532 | MdaXmlMessage(MdaXmlElement** ppMdaXmlRoot); |
533 | MdaXmlMessage(MdaAssistant* pAssistant, BOOL bBreak, MdaXmlElement** ppMdaXmlRoot); |
534 | |
535 | public: |
536 | void SendMessage(); |
537 | void SendMessage(int resourceID); |
538 | void SendMessage(LPCWSTR szMessage); |
539 | void SendMessagef(int resourceID, ...); |
540 | |
541 | private: |
542 | static BOOL IsDebuggerAttached() { WRAPPER_NO_CONTRACT; return ManagedDebuggingAssistants::IsDebuggerAttached(); } |
543 | static BOOL IsManagedDebuggerAttached() { WRAPPER_NO_CONTRACT; return ManagedDebuggingAssistants::IsManagedDebuggerAttached(); } |
544 | static BOOL IsUnmanagedDebuggerAttached() { WRAPPER_NO_CONTRACT; return ManagedDebuggingAssistants::IsUnmanagedDebuggerAttached(); } |
545 | static BOOL ShouldLogToManagedDebugger(); |
546 | |
547 | private: |
548 | void SendEvent(); |
549 | void SendHostEvent(); |
550 | void SendDebugEvent(); |
551 | |
552 | private: |
553 | friend class ManagedDebuggingAssistants; |
554 | friend class MdaFramework; |
555 | |
556 | private: |
557 | BOOL m_bBreak; |
558 | MdaAssistant* m_pMdaAssistant; |
559 | SString m_localizedMessage; |
560 | SString m_englishMessage; |
561 | MdaXmlElement* m_pMdaXmlRoot; |
562 | MdaXmlElement* m_pAssistantXmlRoot; |
563 | MdaXmlIndustry m_mdaXmlIndustry; |
564 | }; |
565 | |
566 | |
567 | // |
568 | // MdaXPath |
569 | // |
570 | class MdaXPath |
571 | { |
572 | public: |
573 | static SArray<MdaXmlElement*>* FindElements(MdaXmlElement* pRoot, LPCWSTR szQuery, SArray<MdaXmlElement*>* pResult) |
574 | { WRAPPER_NO_CONTRACT; MdaXPath query(szQuery); return query.FindElements(pRoot, pResult); } |
575 | static MdaXmlElement* FindElement(MdaXmlElement* pRoot, LPCWSTR szQuery) |
576 | { WRAPPER_NO_CONTRACT; MdaXPath query(szQuery); return query.FindElement(pRoot); } |
577 | static SArray<MdaXmlAttribute*>* FindAttributes(MdaXmlElement* pRoot, LPCWSTR szQuery, SArray<MdaXmlAttribute*>* pResult) |
578 | { WRAPPER_NO_CONTRACT; MdaXPath query(szQuery); return query.FindAttributes(pRoot, pResult); } |
579 | static MdaXmlAttribute* FindAttribute(MdaXmlElement* pRoot, LPCWSTR szQuery) |
580 | { WRAPPER_NO_CONTRACT; MdaXPath query(szQuery); return query.FindAttribute(pRoot); } |
581 | |
582 | public: |
583 | MdaXPath() : m_cArgs(NOT_VARIABLE), m_pCompiledQuery(NULL) { WRAPPER_NO_CONTRACT; } |
584 | MdaXPath(LPCWSTR xpath) : m_cArgs(NOT_VARIABLE) { WRAPPER_NO_CONTRACT; Initialize(xpath); } |
585 | MdaXPath* Initialize(LPCWSTR xpath) { WRAPPER_NO_CONTRACT; m_xpath.Set(xpath); MdaXPathCompiler(this, &m_pCompiledQuery); return this; } |
586 | MdaXmlElement* FindElement(MdaXmlElement* pRoot, ...); |
587 | MdaXmlAttribute* FindAttribute(MdaXmlElement* pRoot, ...); |
588 | SArray<MdaXmlElement*>* FindElements(MdaXmlElement* pRoot, SArray<MdaXmlElement*>* pResult, ...); |
589 | SArray<MdaXmlAttribute*>* FindAttributes(MdaXmlElement* pRoot, SArray<MdaXmlAttribute*>* pResult, ...); |
590 | COUNT_T GetArgCount() { LIMITED_METHOD_CONTRACT; return m_cArgs + 1; } |
591 | |
592 | private: |
593 | class MdaXPathBase; |
594 | class MdaXPathElement; |
595 | class MdaXPathAttribute; |
596 | class MdaXPathResult; |
597 | class MdaXPathLogicalOp; |
598 | |
599 | typedef enum |
600 | { |
601 | XPathVarAttrBool = MdaSchemaPrimitiveBOOL, |
602 | XPathVarAttrSString = MdaSchemaPrimitiveSString, |
603 | XPathVarAttrINT32 = MdaSchemaPrimitiveINT32, |
604 | XPathVarElemDeclDef = XPathVarAttrINT32 + 1, |
605 | XPathVarAttrDeclDef = XPathVarAttrINT32 + 2, |
606 | } XPathVarType; |
607 | |
608 | typedef struct |
609 | { |
610 | union |
611 | { |
612 | MdaElemDeclDef m_elemDeclDef; |
613 | MdaAttrDeclDef m_attrDeclDef; |
614 | BOOL m_bool; |
615 | SString* m_pSstr; |
616 | INT32 m_int32; |
617 | } m_u; |
618 | } MdaXPathVariable; |
619 | |
620 | private: |
621 | void Find(SArray<MdaXPathVariable>& args, SString* pWildCard, va_list argItr); |
622 | static const COUNT_T NOT_VARIABLE = -1; |
623 | |
624 | private: |
625 | class MdaXPathResult |
626 | { |
627 | public: |
628 | MdaXPathResult(SArray<MdaXPathVariable>* args) { LIMITED_METHOD_CONTRACT; Initialize(args); } |
629 | MdaXPathResult(SArray<MdaXmlElement*>* pElements, SArray<MdaXPathVariable>* args) { WRAPPER_NO_CONTRACT; Initialize(args); m_pElements = pElements; } |
630 | MdaXPathResult(SArray<MdaXmlAttribute*>* pAttributes, SArray<MdaXPathVariable>* args) { WRAPPER_NO_CONTRACT; Initialize(args); m_pAttributes = pAttributes; } |
631 | void Initialize(SArray<MdaXPathVariable>* args) { LIMITED_METHOD_CONTRACT; m_args = args; m_pElements = NULL; m_pAttributes = NULL; m_pElement = NULL; m_pAttribute = NULL; m_bIsRoot = TRUE; } |
632 | MdaXmlElement* GetXmlElement() { LIMITED_METHOD_CONTRACT; return m_pElement; } |
633 | MdaXmlAttribute* GetXmlAttribute() { LIMITED_METHOD_CONTRACT; return m_pAttribute; } |
634 | |
635 | void AddMatch(MdaXmlAttribute* pMatch) |
636 | { LIMITED_METHOD_CONTRACT; if (m_pAttributes) m_pAttributes->Append((MdaXmlAttribute*)pMatch); else { ASSERT(!m_pAttribute); m_pAttribute = pMatch; } } |
637 | void AddMatch(MdaXmlElement* pMatch) |
638 | { LIMITED_METHOD_CONTRACT; if (m_pElements) m_pElements->Append((MdaXmlElement*)pMatch); else { ASSERT(!m_pElement); m_pElement = pMatch; } } |
639 | BOOL IsRoot() { LIMITED_METHOD_CONTRACT; if (!m_bIsRoot) return FALSE; m_bIsRoot = FALSE; return TRUE; } |
640 | SArray<MdaXPathVariable>& GetArgs() { LIMITED_METHOD_CONTRACT; return *m_args; } |
641 | |
642 | private: |
643 | BOOL m_bIsRoot; |
644 | SArray<MdaXPathVariable>* m_args; |
645 | SArray<MdaXmlElement*>* m_pElements; |
646 | SArray<MdaXmlAttribute*>* m_pAttributes; |
647 | MdaXmlElement* m_pElement; |
648 | MdaXmlAttribute* m_pAttribute; |
649 | }; |
650 | |
651 | class MdaXPathCompiler |
652 | { |
653 | public: |
654 | MdaXPathCompiler(MdaXPath* pXPath, MdaXPathBase** ppCompiledQuery) |
655 | : m_pXPath(pXPath) { WRAPPER_NO_CONTRACT; m_itr = pXPath->m_xpath.Begin(); NextToken(); *ppCompiledQuery = XPATH(); } |
656 | |
657 | private: |
658 | typedef enum { |
659 | // |
660 | // TOKENS |
661 | // |
662 | MdaXPathIdentifier = 0x0001, |
663 | MdaXPathDot = 0x0002, |
664 | MdaXPathSlash = 0x0004, |
665 | MdaXPathAstrix = 0x0008, |
666 | MdaXPathQuotedString = 0x0010, |
667 | MdaXPathOpenParen = 0x0020, |
668 | MdaXPathCloseParen = 0x0040, |
669 | MdaXPathOpenSqBracket = 0x0080, |
670 | MdaXPathCloseSqBracket = 0x0100, |
671 | MdaXPathLogicalAnd = 0x0200, |
672 | MdaXPathLogicalOr = 0x0400, |
673 | MdaXPathEquals = 0x0800, |
674 | MdaXPathAtSign = 0x1000, |
675 | MdaXPathQMark = 0x2000, |
676 | MdaXPathEnd = 0x4000, |
677 | |
678 | // |
679 | // 1 TOKEN LOOK AHEAD |
680 | // |
681 | MdaXPathSTART = MdaXPathSlash, |
682 | MdaXPathXPATH = MdaXPathSlash, |
683 | MdaXPathATTRIBUTE = MdaXPathAtSign, |
684 | MdaXPathATTRIBUTE_FILTER = MdaXPathAtSign, |
685 | MdaXPathELEMENT = MdaXPathIdentifier | MdaXPathAstrix | MdaXPathQMark, |
686 | MdaXPathELEMENT_EXPR = MdaXPathELEMENT, |
687 | MdaXPathFILTER = MdaXPathELEMENT_EXPR | MdaXPathATTRIBUTE_FILTER, |
688 | MdaXPathFILTER_EXPR = MdaXPathFILTER | MdaXPathOpenParen, |
689 | } MdaXPathTokens; |
690 | |
691 | // |
692 | // LEXIFIER |
693 | // |
694 | private: |
695 | MdaXPathTokens LexAToken(); |
696 | void NextToken() { WRAPPER_NO_CONTRACT; m_currentToken = LexAToken(); } |
697 | BOOL TokenIs(MdaXPathTokens token) { LIMITED_METHOD_CONTRACT; return !!(m_currentToken & token); } |
698 | BOOL TokenIs(int token) { LIMITED_METHOD_CONTRACT; return TokenIs((MdaXPathTokens)token); } |
699 | LPCWSTR GetIdentifier() { WRAPPER_NO_CONTRACT; return m_identifier.GetUnicode(); } |
700 | |
701 | // |
702 | // PRODUCTIONS |
703 | // |
704 | private: |
705 | MdaXPathBase* XPATH(); |
706 | // '/' ATTRIBUTE end |
707 | // '/' ELEMENT_EXPR XPATH |
708 | // '/' ELEMENT_EXPR end |
709 | |
710 | MdaXPathAttribute* ATTRIBUTE(); |
711 | // '@' id |
712 | // '@' '?' |
713 | |
714 | MdaXPathElement* ELEMENT(); |
715 | // id |
716 | // '*' |
717 | // '?' |
718 | |
719 | MdaXPathElement* ELEMENT_EXPR(); |
720 | // ELEMENT '[' FILTER_EXPR ']' |
721 | // ELEMENT |
722 | |
723 | MdaXPathBase* FILTER_EXPR(); |
724 | // FILTER |
725 | // '(' FILTER ')' |
726 | // FILTER '&' FILTER |
727 | // FILTER '|' FILTER |
728 | |
729 | MdaXPathBase* FILTER(); |
730 | // ELEMENT_EXPR |
731 | // ATTRIBUTE_FILTER |
732 | // ELEMENT_EXPR ATTRIBUTE_FILTER |
733 | |
734 | MdaXPathAttribute* ATTRIBUTE_FILTER(); |
735 | // ATTRIBUTE |
736 | // ATTRIBUTE '=' ''' id ''' |
737 | // ATTRIBUTE '=' '?' |
738 | |
739 | private: |
740 | MdaXPath* m_pXPath; |
741 | SString::CIterator m_itr; |
742 | StackSString m_identifier; |
743 | MdaXPathTokens m_currentToken; |
744 | }; |
745 | |
746 | class MdaXPathBase |
747 | { |
748 | public: |
749 | virtual BOOL Run(MdaXmlElement* pElement, MdaXPathResult* pResult) = 0; |
750 | virtual BOOL IsXPathAttribute() { LIMITED_METHOD_CONTRACT; return FALSE; } |
751 | |
752 | private: |
753 | }; |
754 | |
755 | class MdaXPathElement : public MdaXPathBase |
756 | { |
757 | public: |
758 | virtual BOOL Run(MdaXmlElement* pElement, MdaXPathResult* pResult); |
759 | BOOL RunOnChild(MdaXmlElement* pElement, MdaXPathResult* pResult); |
760 | |
761 | public: |
762 | MdaXPathElement() : m_name(MdaElemUndefined), m_nameArg(NOT_VARIABLE), m_bIsTarget(FALSE), m_pChild(NULL), m_pQualifier(NULL) { LIMITED_METHOD_CONTRACT; } |
763 | MdaXPathBase* MarkAsTarget() { LIMITED_METHOD_CONTRACT; m_bIsTarget = TRUE; return this; }; |
764 | MdaXPathElement* SetChild(MdaXPathBase* pChild) { LIMITED_METHOD_CONTRACT; m_pChild = pChild; return this; } |
765 | MdaXPathElement* SetQualifier(MdaXPathBase* pQualifier) { LIMITED_METHOD_CONTRACT; m_pQualifier = pQualifier; return this; } |
766 | MdaXPathElement* Initialize() { LIMITED_METHOD_CONTRACT; return this; } |
767 | MdaXPathElement* Initialize(MdaElemDeclDef identifier) { LIMITED_METHOD_CONTRACT; m_name = identifier; return this; } |
768 | MdaXPathElement* Initialize(COUNT_T identifier) { LIMITED_METHOD_CONTRACT; m_nameArg = identifier; return this; } |
769 | |
770 | private: |
771 | MdaElemDeclDef m_name; |
772 | COUNT_T m_nameArg; |
773 | BOOL m_bIsTarget; |
774 | MdaXPathBase* m_pChild; |
775 | MdaXPathBase* m_pQualifier; |
776 | }; |
777 | |
778 | class MdaXPathAttribute : public MdaXPathBase |
779 | { |
780 | public: |
781 | MdaXPathAttribute() : m_name(MdaAttrUndefined), m_nameArg(NOT_VARIABLE), m_valueArg(NOT_VARIABLE) { WRAPPER_NO_CONTRACT; } |
782 | virtual BOOL Run(MdaXmlElement* pElement, MdaXPathResult* pResult); |
783 | virtual BOOL IsXPathAttribute() { LIMITED_METHOD_CONTRACT; return TRUE; } |
784 | |
785 | public: |
786 | MdaXPathBase* MarkAsTarget() { LIMITED_METHOD_CONTRACT; m_bIsTarget = TRUE; return this; }; |
787 | MdaXPathAttribute* SetName(MdaAttrDeclDef name) { WRAPPER_NO_CONTRACT; m_name = name; return this; } |
788 | MdaXPathAttribute* SetValue(LPCWSTR value) { WRAPPER_NO_CONTRACT; m_value.Set(value); return this; } |
789 | MdaXPathAttribute* SetName(COUNT_T name) { WRAPPER_NO_CONTRACT; m_nameArg = name; return this; } |
790 | MdaXPathAttribute* SetValue(COUNT_T value) { WRAPPER_NO_CONTRACT; m_valueArg = value; return this; } |
791 | |
792 | private: |
793 | BOOL m_bIsTarget; |
794 | MdaAttrDeclDef m_name; |
795 | COUNT_T m_nameArg; |
796 | SString m_value; |
797 | COUNT_T m_valueArg; |
798 | }; |
799 | |
800 | class MdaXPathLogicalOp : public MdaXPathBase |
801 | { |
802 | public: |
803 | virtual BOOL Run(MdaXmlElement* pElement, MdaXPathResult* pResult); |
804 | |
805 | public: |
806 | MdaXPathLogicalOp* Initialize(BOOL andOp, MdaXPathBase* pLhs, MdaXPathBase* pRhs) |
807 | { LIMITED_METHOD_CONTRACT; m_andOp = andOp; m_pLhs = pLhs; m_pRhs = pRhs; return this; } |
808 | |
809 | private: |
810 | BOOL m_andOp; |
811 | MdaXPathBase* m_pLhs; |
812 | MdaXPathBase* m_pRhs; |
813 | }; |
814 | |
815 | private: |
816 | COUNT_T m_cArgs; |
817 | InlineSArray<XPathVarType, 20> m_argTypes; |
818 | StackSString m_xpath; |
819 | MdaXPathBase* m_pCompiledQuery; |
820 | MdaFactory<MdaXPathElement> m_elementFactory; |
821 | MdaFactory<MdaXPathAttribute> m_attrFactory; |
822 | MdaFactory<MdaXPathLogicalOp> m_logicalOpFactory; |
823 | }; |
824 | |
825 | |
826 | // |
827 | // MdaSchema |
828 | // |
829 | class MdaSchema |
830 | { |
831 | private: |
832 | static void Initialize(); |
833 | |
834 | public: |
835 | // SPTR_DECL(RangeSection, m_RangeTree); |
836 | // SPTR_IMPL(RangeSection, ExecutionManager, m_RangeTree); |
837 | |
838 | static MdaElemDeclDef GetElementType(LPCWSTR name, BOOL bAssertDefined = TRUE); |
839 | static LPCWSTR GetElementName(MdaElemDeclDef type); |
840 | static MdaAttrDeclDef GetAttributeType(LPCWSTR name, BOOL bAssertDefined = TRUE); |
841 | static LPCWSTR GetAttributeName(MdaAttrDeclDef type); |
842 | |
843 | public: |
844 | static LPCWSTR g_arElementNames[MdaElemEnd]; |
845 | |
846 | private: |
847 | static LPCWSTR g_arAttributeNames[MdaAttrEnd]; |
848 | static MdaFactory<SString>* g_pSstringFactory; |
849 | static MdaHashtable<MdaElemDeclDef>* g_pHtElementType; |
850 | static MdaHashtable<MdaAttrDeclDef>* g_pHtAttributeType; |
851 | static LPCWSTR ToLowerFirstChar(LPCWSTR name); |
852 | |
853 | private: |
854 | class MdaSchemaBase; |
855 | class MdaSchemaAttribute; |
856 | class MdaSchemaSequence; |
857 | class MdaSchemaChoice; |
858 | class MdaSchemaComplexType; |
859 | class MdaSchemaElement; |
860 | class MdaSchemaGroup; |
861 | class MdaSchemaGroupRef; |
862 | class MdaSchemaExtension; |
863 | class MdaSchemaDeclDefRef; |
864 | |
865 | private: |
866 | class ValidationResult |
867 | { |
868 | public: |
869 | ValidationResult() { LIMITED_METHOD_CONTRACT; ResetResult(); } |
870 | void ResetResult() { LIMITED_METHOD_CONTRACT; m_bValid = TRUE; m_pViolatedElement = NULL; m_pViolatingElement = NULL; m_pXmlRoot = NULL; m_pSchema = NULL; } |
871 | BOOL ValidationFailed() { LIMITED_METHOD_CONTRACT; return !m_bValid; } |
872 | void Initialize(MdaSchema* pSchema, MdaXmlElement* pRoot) { LIMITED_METHOD_CONTRACT; m_pXmlRoot = pRoot; m_pSchema = pSchema; } |
873 | void SetError() { LIMITED_METHOD_CONTRACT; m_bValid = FALSE; } |
874 | void SetError(MdaSchemaBase* pViolatedElement, MdaXmlElement* pViolatingElement) |
875 | { LIMITED_METHOD_CONTRACT; m_bValid = FALSE; m_pViolatedElement = pViolatedElement; m_pViolatingElement = pViolatingElement; } |
876 | |
877 | private: |
878 | friend class MdaXmlValidationError; |
879 | |
880 | private: |
881 | BOOL m_bValid; |
882 | MdaXmlElement* m_pXmlRoot; |
883 | MdaSchema* m_pSchema; |
884 | MdaSchemaBase* m_pViolatedElement; |
885 | MdaXmlElement* m_pViolatingElement; |
886 | }; |
887 | |
888 | private: |
889 | static BOOL MayHaveAttr(MdaSchemaBase* pBase) { LIMITED_METHOD_CONTRACT; return MdaSchemaTypeToMetaType[pBase->GetSchemaType()] & MdaSchemaMataMayHaveAttributes; } |
890 | static BOOL IsPattern(MdaSchemaBase* pBase) { LIMITED_METHOD_CONTRACT; return MdaSchemaTypeToMetaType[pBase->GetSchemaType()] & MdaSchemaMataTypePattern; } |
891 | static BOOL IsRef(MdaSchemaBase* pBase) { LIMITED_METHOD_CONTRACT; return MdaSchemaTypeToMetaType[pBase->GetSchemaType()] & MdaSchemaMataTypeRef; } |
892 | static BOOL IsDeclDef(MdaSchemaBase* pBase) { LIMITED_METHOD_CONTRACT; return MdaSchemaTypeToMetaType[pBase->GetSchemaType()] & MdaSchemaMataTypeDeclDef; } |
893 | static BOOL IsDeclDefRef(MdaSchemaBase* pBase) { WRAPPER_NO_CONTRACT; return IsDeclDef(pBase) || IsRef(pBase); } |
894 | static MdaSchemaDeclDefRef* AsDeclDefRef(MdaSchemaBase* pBase) { WRAPPER_NO_CONTRACT; if (!IsDeclDefRef(pBase)) return NULL; return (MdaSchemaDeclDefRef*)pBase; } |
895 | static MdaSchemaDeclDefRef* ToDeclDefRef(MdaSchemaBase* pBase) { WRAPPER_NO_CONTRACT; ASSERT(IsDeclDefRef(pBase)); return (MdaSchemaDeclDefRef*)pBase; } |
896 | static MdaSchemaDeclDefRef* ToDeclDef(MdaSchemaBase* pBase) { WRAPPER_NO_CONTRACT; ASSERT(IsDeclDef(pBase)); return (MdaSchemaDeclDefRef*)pBase; } |
897 | static MdaSchemaDeclDefRef* ToRef(MdaSchemaBase* pBase) { WRAPPER_NO_CONTRACT; ASSERT(IsRef(pBase)); return (MdaSchemaDeclDefRef*)pBase; } |
898 | |
899 | public: |
900 | typedef enum { |
901 | MdaSchemaSequenceType, |
902 | MdaSchemaChoiceType, |
903 | MdaSchemaGroupType, |
904 | MdaSchemaGroupRefType, |
905 | MdaSchemaRootType, |
906 | MdaSchemaAttributeType, |
907 | MdaSchemaElementType, |
908 | MdaSchemaComplexTypeType, |
909 | MdaSchemaComplexTypeDefType, |
910 | MdaSchemaElementRefTyp, |
911 | MdaSchemaExtensionType, |
912 | MdaSchemaElementRefTypeType, |
913 | MdaSchemaComplexContentType, |
914 | MdaSchemaElementAnyType, |
915 | MdaSchemaTypeEnd, |
916 | } MdaSchemaType; |
917 | |
918 | typedef enum { |
919 | MdaSchemaMataNone = 0x0, |
920 | MdaSchemaMataTypePattern = 0x1, |
921 | MdaSchemaMataTypeDeclDef = 0x2, |
922 | MdaSchemaMataTypeRef = 0x4, |
923 | MdaSchemaMataMayHaveAttributes = 0x8, |
924 | } MdaSchemaMetaType; |
925 | |
926 | private: |
927 | static MdaElemDeclDef MdaSchemaTypeToElemDef[]; |
928 | static MdaSchemaMetaType MdaSchemaTypeToMetaType[]; |
929 | |
930 | class MdaSchemaBase |
931 | { |
932 | public: |
933 | virtual MdaSchemaType GetSchemaType() = 0; |
934 | virtual MdaElemDeclDef GetSchemaDeclDef() { LIMITED_METHOD_CONTRACT; return MdaSchemaTypeToElemDef[GetSchemaType()]; } |
935 | virtual BOOL Validate(MdaXmlElement* pElement, ValidationResult* pResult); |
936 | virtual BOOL ValidatePattern(MdaXmlElement* pElement, ValidationResult* pResult, COUNT_T* pCount) { UNREACHABLE(); } |
937 | virtual void SetAttributes(MdaXmlElement* pXml) { LIMITED_METHOD_CONTRACT; } |
938 | |
939 | public: |
940 | void Verify(MdaSchemaType schemaType, MdaElemDeclDef declDef) |
941 | { |
942 | LIMITED_METHOD_CONTRACT; |
943 | // Look for missmatch element in your schema ELEMENT(Foo) ... ELEMENT_END(bar) |
944 | ASSERT(schemaType == GetSchemaType() && |
945 | W("Mismatch element in your schema ELEMENT(foo) ... TYPE_END(foo) -- attach debugger and look for MdaAssistantSchema on stack" )); |
946 | ASSERT(ToDeclDef(this)->GetDeclDef() == declDef && |
947 | W("Mismatch declaration in your schema ELEMENT(Foo) ... ELEMENT_END(bar) -- attach debugger and look for MdaAssistantSchema on stack" )); |
948 | } |
949 | void Verify(MdaSchemaType schemaType, MdaSchemaBase** ppRef) |
950 | { |
951 | LIMITED_METHOD_CONTRACT; |
952 | // Look for missmatch element in your schema ELEMENT(Foo) ... ELEMENT_END(bar) |
953 | ASSERT(schemaType == GetSchemaType() && |
954 | W("Mismatch element in your schema ELEMENT(foo) ... TYPE_END(foo) -- attach debugger and look for MdaAssistantSchema on stack" )); |
955 | ASSERT(ToRef(this)->m_ppRef == ppRef && |
956 | W("Mismatch declaration in your schema ELEMENT(foo) ... ELEMENT_END(bar) -- attach debugger and look for MdaAssistantSchema on stack" )); |
957 | } |
958 | void Verify(MdaSchemaType schemaType) |
959 | { |
960 | LIMITED_METHOD_CONTRACT; |
961 | // Look for missmatch element in your schema ELEMENT(Foo) ... ELEMENT_END(bar) |
962 | ASSERT(schemaType == GetSchemaType() && |
963 | W("Mismatch element in your schema ELEMENT(foo) ... TYPE_END(foo) -- attach debugger and look for MdaAssistantSchema on stack" )); |
964 | } |
965 | |
966 | public: |
967 | MdaXmlElement* ToXml(MdaXmlIndustry* pMdaXmlIndustry, MdaSchemaBase* pViolation = NULL); |
968 | MdaXmlElement* ToXml(MdaXmlElement* pXmlRoot) { WRAPPER_NO_CONTRACT; return ToXml(pXmlRoot, NULL); } |
969 | MdaXmlElement* ToXml(MdaXmlElement* pXmlRoot, MdaSchemaBase* pViolation); |
970 | void AddChild(MdaSchemaBase* pElement); |
971 | LPCWSTR GetName() { WRAPPER_NO_CONTRACT; return GetElementName(GetSchemaDeclDef()); } |
972 | friend class MdaSchemaExtension; |
973 | |
974 | protected: |
975 | InlineSArray<MdaSchemaBase*, MDA_XML_ELEMENT_CHILDREN> m_children; |
976 | virtual InlineSArray<MdaSchemaAttribute*, MDA_XML_ELEMENT_CHILDREN>& GetAttributes() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); } |
977 | }; |
978 | |
979 | // <xs:schema> |
980 | class MdaSchemaRoot : public MdaSchemaBase |
981 | { |
982 | public: |
983 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaRootType; } |
984 | virtual BOOL Validate(MdaXmlElement* pElement, ValidationResult* pResult); |
985 | }; |
986 | |
987 | // <xs:attribute name="enable" value="xs:boolean" required="true" default="true"> |
988 | static BOOL MdaSchema::Validate(MdaSchemaAttribute* pThis, MdaXmlElement* pElement, ValidationResult* pResult); |
989 | class MdaSchemaAttribute : public MdaSchemaBase |
990 | { |
991 | public: |
992 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaAttributeType; } |
993 | virtual BOOL Validate(MdaXmlElement* pElement, ValidationResult* pResult) { WRAPPER_NO_CONTRACT; return MdaSchema::Validate(this, pElement, pResult); } |
994 | |
995 | public: |
996 | void SetAttributes(MdaXmlElement* pXml); |
997 | MdaSchemaAttribute* Initialize(MdaAttrDeclDef name, MdaSchemaPrimitive type, BOOL bRequired, LPCWSTR szDefault) |
998 | { WRAPPER_NO_CONTRACT; m_declDef = name; m_type = type; m_bRequired = bRequired; m_szDefault = szDefault; return this; } |
999 | |
1000 | private: |
1001 | friend MdaSchema; |
1002 | |
1003 | private: |
1004 | BOOL m_bRequired; |
1005 | SString m_szDefault; |
1006 | MdaAttrDeclDef m_declDef; |
1007 | MdaSchemaPrimitive m_type; |
1008 | }; |
1009 | |
1010 | // <xs:sequence minOccures="0" maxOccures="unbounded"> |
1011 | class MdaSchemaSequence : public MdaSchemaBase |
1012 | { |
1013 | public: |
1014 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaSequenceType; } |
1015 | virtual BOOL ValidatePattern(MdaXmlElement* pElement, ValidationResult* pResult, COUNT_T* pCount); |
1016 | virtual void SetAttributes(MdaXmlElement* pXml); |
1017 | |
1018 | public: |
1019 | MdaSchemaSequence* Initialize(COUNT_T min, COUNT_T max) { WRAPPER_NO_CONTRACT; m_min = min; m_max = max; return this; } |
1020 | |
1021 | private: |
1022 | BOOL m_VsHack; |
1023 | COUNT_T m_min; |
1024 | COUNT_T m_max; |
1025 | }; |
1026 | |
1027 | // <xs:choice> |
1028 | class MdaSchemaChoice : public MdaSchemaBase |
1029 | { |
1030 | public: |
1031 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaChoiceType; } |
1032 | virtual BOOL ValidatePattern(MdaXmlElement* pElement, ValidationResult* pResult, COUNT_T* pCount); |
1033 | }; |
1034 | |
1035 | // <xs:complexContent> |
1036 | class MdaSchemaComplexContent : public MdaSchemaBase |
1037 | { |
1038 | public: |
1039 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaComplexContentType; } |
1040 | virtual BOOL Validate(MdaXmlElement* pElement, ValidationResult* pResult); |
1041 | }; |
1042 | |
1043 | // <xs:complexType> |
1044 | class MdaSchemaComplexType : public MdaSchemaBase |
1045 | { |
1046 | public: |
1047 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaComplexTypeType; } |
1048 | virtual BOOL Validate(MdaXmlElement* pElement, ValidationResult* pResult); |
1049 | virtual InlineSArray<MdaSchemaAttribute*, MDA_XML_ELEMENT_CHILDREN>& GetAttributes() { LIMITED_METHOD_CONTRACT; return m_attributes; } |
1050 | |
1051 | private: |
1052 | friend class MdaSchemaExtension; |
1053 | InlineSArray<MdaSchemaAttribute*, MDA_XML_ELEMENT_CHILDREN> m_attributes; |
1054 | }; |
1055 | |
1056 | class MdaSchemaDeclDefRef : public MdaSchemaBase |
1057 | { |
1058 | public: |
1059 | virtual void SetAttributes(MdaXmlElement* pXml); |
1060 | |
1061 | public: |
1062 | MdaSchemaDeclDefRef() : m_declDef(MdaElemUndefined), m_ppRef(NULL) { LIMITED_METHOD_CONTRACT; } |
1063 | LPCWSTR GetDeclDefName() { WRAPPER_NO_CONTRACT; ASSERT(IsDeclDef(this)); return GetElementName(m_declDef); } |
1064 | LPCWSTR GetRefName() { LIMITED_METHOD_CONTRACT; return GetRef()->GetDeclDefName(); } |
1065 | MdaElemDeclDef GetDeclDef() { LIMITED_METHOD_CONTRACT; ASSERT(IsDeclDef(this)); return m_declDef; } |
1066 | MdaSchemaDeclDefRef* GetRef() { LIMITED_METHOD_CONTRACT; ASSERT(IsRef(this)); return ToDeclDef(*m_ppRef); } |
1067 | BOOL IsDefinition() { LIMITED_METHOD_CONTRACT; ASSERT(IsDeclDef(this)); return m_declDef < MdaElemDef(Max); } |
1068 | |
1069 | public: |
1070 | MdaSchemaDeclDefRef* InitRef(MdaSchemaBase** ppRef) { WRAPPER_NO_CONTRACT; ASSERT(IsRef(this)); m_ppRef = ppRef; return this; } |
1071 | MdaSchemaDeclDefRef* InitDeclDef(MdaElemDeclDef declDef) { WRAPPER_NO_CONTRACT; ASSERT(IsDeclDef(this)); m_declDef = declDef; return this; } |
1072 | |
1073 | private: |
1074 | friend class MdaSchemaBase; |
1075 | MdaSchemaBase** m_ppRef; |
1076 | MdaElemDeclDef m_declDef; |
1077 | }; |
1078 | |
1079 | // <xs:group name="myGroup"> |
1080 | class MdaSchemaGroup : public MdaSchemaDeclDefRef |
1081 | { |
1082 | public: |
1083 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaGroupType; } |
1084 | virtual BOOL ValidatePattern(MdaXmlElement* pElement, ValidationResult* pResult, COUNT_T* pCount); |
1085 | }; |
1086 | |
1087 | // <xs:element name="myGroup"> |
1088 | class MdaSchemaElement : public MdaSchemaDeclDefRef |
1089 | { |
1090 | public: |
1091 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaElementType; } |
1092 | virtual BOOL Validate(MdaXmlElement* pElement, ValidationResult* pResult); |
1093 | }; |
1094 | |
1095 | // <xs:complexType name="myElementType"> |
1096 | class MdaSchemaComplexTypeDef : public MdaSchemaDeclDefRef |
1097 | { |
1098 | public: |
1099 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaComplexTypeDefType; } |
1100 | virtual BOOL Validate(MdaXmlElement* pElement, ValidationResult* pResult); |
1101 | virtual InlineSArray<MdaSchemaAttribute*, MDA_XML_ELEMENT_CHILDREN>& GetAttributes() { LIMITED_METHOD_CONTRACT; return m_attributes; } |
1102 | |
1103 | private: |
1104 | friend class MdaSchemaExtension; |
1105 | InlineSArray<MdaSchemaAttribute*, MDA_XML_ELEMENT_CHILDREN> m_attributes; |
1106 | }; |
1107 | |
1108 | // <xs:group ref="myGroup"> |
1109 | class MdaSchemaGroupRef : public MdaSchemaDeclDefRef |
1110 | { |
1111 | public: |
1112 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaGroupRefType; } |
1113 | virtual BOOL ValidatePattern(MdaXmlElement* pElement, ValidationResult* pResult, COUNT_T* pCount); |
1114 | }; |
1115 | |
1116 | // <xs:extension base="myElementType"> |
1117 | class MdaSchemaExtension : public MdaSchemaDeclDefRef |
1118 | { |
1119 | public: |
1120 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaExtensionType; } |
1121 | virtual BOOL Validate(MdaXmlElement* pXml, ValidationResult* pResult); |
1122 | virtual InlineSArray<MdaSchemaAttribute*, MDA_XML_ELEMENT_CHILDREN>& GetAttributes() { LIMITED_METHOD_CONTRACT; return m_attributes; } |
1123 | |
1124 | public: |
1125 | MdaSchemaExtension() { LIMITED_METHOD_CONTRACT; } |
1126 | |
1127 | private: |
1128 | InlineSArray<MdaSchemaAttribute*, MDA_XML_ELEMENT_CHILDREN> m_attributes; |
1129 | }; |
1130 | |
1131 | // <xs:element ref="myElement"> |
1132 | class MdaSchemaElementRef : public MdaSchemaDeclDefRef |
1133 | { |
1134 | public: |
1135 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaElementRefTyp; } |
1136 | virtual BOOL Validate(MdaXmlElement* pElement, ValidationResult* pResult); |
1137 | }; |
1138 | |
1139 | // <xs:element name="myElementAsMyType" type="myType"> |
1140 | class MdaSchemaElementRefType : public MdaSchemaDeclDefRef |
1141 | { |
1142 | public: |
1143 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaElementRefTypeType; } |
1144 | virtual BOOL Validate(MdaXmlElement* pElement, ValidationResult* pResult); |
1145 | }; |
1146 | |
1147 | // <xs:element name="myElementAsMyType" type="xs:anyType"> |
1148 | class MdaSchemaElementAny : public MdaSchemaDeclDefRef |
1149 | { |
1150 | public: |
1151 | virtual MdaSchemaType GetSchemaType() { LIMITED_METHOD_CONTRACT; return MdaSchemaElementAnyType; } |
1152 | virtual BOOL Validate(MdaXmlElement* pElement, ValidationResult* pResult); |
1153 | }; |
1154 | /* |
1155 | // <xs:simpleType name="mySimpleType> |
1156 | class MdaSimpleTypeDef : public MdaSchemaDeclDefRef |
1157 | { |
1158 | } |
1159 | |
1160 | // <xs:restriction base="xs:string> |
1161 | class MdaRestriction : public MdaSchemaDeclDefRef |
1162 | { |
1163 | } |
1164 | |
1165 | // <xs:enumeration value="blue"> |
1166 | class MdaEnumeration : public MdaSchemaBase |
1167 | { |
1168 | } |
1169 | */ |
1170 | private: |
1171 | MdaSchema(); |
1172 | virtual LPCWSTR SetRootAttributes(MdaXmlElement* pXml) = 0; |
1173 | ValidationResult* Validate(MdaXmlElement* pRoot, ValidationResult* pResult); |
1174 | MdaXmlElement* ToXml(MdaXmlElement* pXmlRoot) { WRAPPER_NO_CONTRACT; return m_tos->ToXml(pXmlRoot); } |
1175 | MdaXmlElement* ToXml(MdaXmlIndustry* pMdaXmlIndustry) { WRAPPER_NO_CONTRACT; return m_tos->ToXml(pMdaXmlIndustry); } |
1176 | MdaXmlElement* ToXml(MdaXmlIndustry* pMdaXmlIndustry, MdaSchemaBase* pXsdViolation) { WRAPPER_NO_CONTRACT; return m_tos->ToXml(pMdaXmlIndustry, pXsdViolation); } |
1177 | |
1178 | private: // Assistant Definitions |
1179 | void DefineAssistant(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; m_currentAssistant = name; } |
1180 | void DefineAssistantEnd(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; m_currentAssistant = MdaElemUndefined; } |
1181 | void DefineAssistantInput(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; ASSERT(m_currentAssistant == name); AddExtendElement(name, MdaElemDef(Assistant)); } |
1182 | void DefineAssistantInputEnd(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; ASSERT(m_currentAssistant == name); AddExtendElementEnd(name, MdaElemDef(Assistant)); } |
1183 | void DefineAssistantOutput(MdaElemDeclDef name, MdaElemDeclDef msgName) { WRAPPER_NO_CONTRACT; ASSERT(m_currentAssistant == name); AddExtendElement(msgName, MdaElemDef(AssistantMsgType)); } |
1184 | void DefineAssistantOutputEnd(MdaElemDeclDef name, MdaElemDeclDef msgName) { WRAPPER_NO_CONTRACT; ASSERT(m_currentAssistant == name); AddExtendElementEnd(msgName, MdaElemDef(AssistantMsgType)); } |
1185 | |
1186 | private: // <xs:*> |
1187 | void DefineSchema() { WRAPPER_NO_CONTRACT; m_tos = m_schemaRootFactory.Create(); } |
1188 | void DefineSchemaEnd() { CONTRACTL {NOTHROW; GC_NOTRIGGER; SO_TOLERANT; MODE_ANY; PRECONDITION(m_stack.GetDepth() == 0); } CONTRACTL_END; } |
1189 | void AddElement(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; Push(CreateDeclDef(name, &m_elementFactory)); Push(m_complexTypeFactory.Create()); } |
1190 | void AddElementRefType(MdaElemDeclDef name, MdaElemDeclDef type) { WRAPPER_NO_CONTRACT; AddTerminal(CreateDeclDef(name, &m_elementRefTypeFactory)->InitRef(GetDef(type))); } |
1191 | void AddElementAny(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; AddTerminal(CreateDeclDef(name, &m_elementAnyFactory)); } |
1192 | void AddExtendElement(MdaElemDeclDef name, MdaElemDeclDef type) { WRAPPER_NO_CONTRACT; AddElement(name); AddExtension(type); } |
1193 | void AddComplexType(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; Push(CreateDeclDef(name, &m_complexTypeDefFactory)); } |
1194 | void AddExtendType(MdaElemDeclDef name, MdaElemDeclDef type) { WRAPPER_NO_CONTRACT; AddComplexType(name); AddExtension(type); } |
1195 | void AddExtension(MdaElemDeclDef type) { WRAPPER_NO_CONTRACT; Push(m_complexContentFactory.Create()); Push(m_extensionFactory.Create()->InitRef(GetDef(type))); } |
1196 | void RefElement(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; AddTerminal(m_elementRefFactory.Create()->InitRef(GetDef(name))); } |
1197 | void RefGroup(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; AddTerminal(m_groupRefFactory.Create()->InitRef(GetDef(name))); } |
1198 | void AddChoice() { WRAPPER_NO_CONTRACT; Push(m_choiceFactory.Create()); } |
1199 | void AddGroup(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; Push(CreateDeclDef(name, &m_groupFactory)); } |
1200 | void AddSequence(COUNT_T minOccures, COUNT_T maxOccures) { WRAPPER_NO_CONTRACT; Push(m_sequenceFactory.Create()->Initialize(minOccures, maxOccures)); } |
1201 | void AddAttribute(MdaAttrDeclDef name, MdaSchemaPrimitive type, BOOL bRequired, LPCWSTR szDefault) |
1202 | { WRAPPER_NO_CONTRACT; AddTerminal(m_attrFactory.Create()->Initialize(name, type, bRequired, szDefault)); } |
1203 | |
1204 | private: // </xs:*> |
1205 | void AddElementEnd(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; Pop()->Verify(MdaSchemaComplexTypeType); Pop()->Verify(MdaSchemaElementType, name); } |
1206 | void AddExtendElementEnd(MdaElemDeclDef name, MdaElemDeclDef type) { WRAPPER_NO_CONTRACT; AddExtensionEnd(type); AddElementEnd(name); } |
1207 | void AddComplexTypeEnd(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; Pop()->Verify(MdaSchemaComplexTypeDefType, name); } |
1208 | void AddExtendTypeEnd(MdaElemDeclDef name, MdaElemDeclDef type) { WRAPPER_NO_CONTRACT; AddExtensionEnd(type); AddComplexTypeEnd(name); } |
1209 | void AddExtensionEnd(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; Pop()->Verify(MdaSchemaExtensionType, GetDef(name)); Pop()->Verify(MdaSchemaComplexContentType); } |
1210 | void AddGroupEnd(MdaElemDeclDef name) { WRAPPER_NO_CONTRACT; Pop()->Verify(MdaSchemaGroupType, name); } |
1211 | void AddChoiceEnd() { WRAPPER_NO_CONTRACT; Pop()->Verify(MdaSchemaChoiceType); } |
1212 | void AddSequenceEnd() { WRAPPER_NO_CONTRACT; Pop()->Verify(MdaSchemaSequenceType); } |
1213 | |
1214 | private: |
1215 | MdaSchemaBase* Pop() { WRAPPER_NO_CONTRACT; ASSERT(m_stack.GetDepth() > 0); MdaSchemaBase* popped = m_tos; m_tos = m_stack.Pop(); return popped; } |
1216 | void AddTerminal(MdaSchemaBase* pSchemaBase) { WRAPPER_NO_CONTRACT; m_tos->AddChild(pSchemaBase); } |
1217 | |
1218 | template<typename TYPE> |
1219 | TYPE* Push(TYPE* pChild) { WRAPPER_NO_CONTRACT; AddTerminal(pChild); m_stack.Push(m_tos); m_tos = pChild; return pChild; } |
1220 | |
1221 | template<typename TYPE> |
1222 | TYPE* CreateDeclDef(MdaElemDeclDef name, MdaFactory<TYPE>* m_pFactory) |
1223 | { |
1224 | WRAPPER_NO_CONTRACT; |
1225 | |
1226 | TYPE* pDeclDef = m_pFactory->Create(); |
1227 | pDeclDef->InitDeclDef(name); |
1228 | |
1229 | if (pDeclDef->IsDefinition()) |
1230 | { |
1231 | ASSERT(m_stack.GetDepth() == 0); |
1232 | *GetDef(name) = pDeclDef; |
1233 | } |
1234 | |
1235 | return pDeclDef; |
1236 | } |
1237 | |
1238 | MdaSchemaBase** GetDef(MdaElemDeclDef type) { WRAPPER_NO_CONTRACT; return &m_definitions[type]; } |
1239 | |
1240 | private: |
1241 | friend class ManagedDebuggingAssistants; |
1242 | friend class MdaFramework; |
1243 | friend class MdaXmlElement; |
1244 | friend class MdaXmlAttribute; |
1245 | friend class MdaAssistant; |
1246 | friend class MdaAssistantSchema; |
1247 | friend class MdaAssistantMsgSchema; |
1248 | friend class MdaSchemaSchema; |
1249 | friend class MdaXPath; |
1250 | friend class MdaXmlMessage; |
1251 | friend class MdaXmlValidationError; |
1252 | |
1253 | private: |
1254 | MdaFactory<MdaSchemaRoot> m_schemaRootFactory; |
1255 | MdaFactory<MdaSchemaAttribute> m_attrFactory; |
1256 | MdaFactory<MdaSchemaSequence> m_sequenceFactory; |
1257 | MdaFactory<MdaSchemaChoice> m_choiceFactory; |
1258 | MdaFactory<MdaSchemaGroup> m_groupFactory; |
1259 | MdaFactory<MdaSchemaGroupRef> m_groupRefFactory; |
1260 | MdaFactory<MdaSchemaComplexTypeDef> m_complexTypeDefFactory; |
1261 | MdaFactory<MdaSchemaComplexType> m_complexTypeFactory; |
1262 | MdaFactory<MdaSchemaComplexContent> m_complexContentFactory; |
1263 | MdaFactory<MdaSchemaElement> m_elementFactory; |
1264 | MdaFactory<MdaSchemaElementRef> m_elementRefFactory; |
1265 | MdaFactory<MdaSchemaElementRefType> m_elementRefTypeFactory; |
1266 | MdaFactory<MdaSchemaExtension> m_extensionFactory; |
1267 | MdaFactory<MdaSchemaElementAny> m_elementAnyFactory; |
1268 | |
1269 | private: |
1270 | MdaSchemaBase* m_definitions[MdaElemEnd]; |
1271 | MdaElemDeclDef m_currentAssistant; |
1272 | MdaSchemaBase* m_tos; |
1273 | MdaStack<MdaSchemaBase*> m_stack; |
1274 | }; |
1275 | |
1276 | |
1277 | // |
1278 | // MdaAssistantMsgSchema |
1279 | // |
1280 | class MdaAssistantSchema : public MdaSchema |
1281 | { |
1282 | private: |
1283 | MdaAssistantSchema(); |
1284 | LPCWSTR SetRootAttributes(MdaXmlElement* pXml); |
1285 | |
1286 | private: |
1287 | friend class ManagedDebuggingAssistants; |
1288 | friend class MdaXmlElement; |
1289 | friend class MdaAssistant; |
1290 | }; |
1291 | |
1292 | |
1293 | // |
1294 | // MdaAssistantMsgSchema |
1295 | // |
1296 | class MdaAssistantMsgSchema : public MdaSchema |
1297 | { |
1298 | private: |
1299 | MdaAssistantMsgSchema(); |
1300 | LPCWSTR SetRootAttributes(MdaXmlElement* pXml); |
1301 | |
1302 | private: |
1303 | friend class ManagedDebuggingAssistants; |
1304 | friend class MdaXmlElement; |
1305 | friend class MdaAssistant; |
1306 | }; |
1307 | |
1308 | |
1309 | // |
1310 | // MdaSchemaSchema |
1311 | // |
1312 | class MdaSchemaSchema : public MdaSchema |
1313 | { |
1314 | private: |
1315 | MdaSchemaSchema(); |
1316 | LPCWSTR SetRootAttributes(MdaXmlElement* pXml); |
1317 | |
1318 | private: |
1319 | friend class ManagedDebuggingAssistants; |
1320 | friend class MdaXmlElement; |
1321 | friend class MdaAssistant; |
1322 | }; |
1323 | |
1324 | |
1325 | // |
1326 | // MdaQuery |
1327 | // |
1328 | |
1329 | BOOL IsJustMyCode(MethodDesc* pMethodDesc); |
1330 | |
1331 | class MdaQuery |
1332 | { |
1333 | private: |
1334 | class CompiledQuery |
1335 | { |
1336 | public: |
1337 | CompiledQuery(); |
1338 | |
1339 | public: |
1340 | BOOL Test(MethodDesc* pMethodDesc); |
1341 | BOOL Test(FieldDesc* pFieldDesc); |
1342 | BOOL Test(MethodTable* pMethodTable); |
1343 | |
1344 | public: |
1345 | void SetName(LPCWSTR name); |
1346 | void SetNestedTypeName(LPCWSTR name); |
1347 | void SetMemberName(LPCWSTR name) { WRAPPER_NO_CONTRACT; m_sszMember.Set(name); } |
1348 | void SetAnyMember(); |
1349 | void SetAnyType(); |
1350 | void SetJustMyCode() { LIMITED_METHOD_CONTRACT; m_bJustMyCode = TRUE; } |
1351 | |
1352 | private: |
1353 | BOOL Test(SString* psszName, MethodTable* pMethodTable); |
1354 | |
1355 | private: |
1356 | friend class MdaQuery; |
1357 | |
1358 | private: |
1359 | BOOL m_bAnyMember; |
1360 | BOOL m_bAnyType; |
1361 | BOOL m_bJustMyCode; |
1362 | StackSString m_sszFullname; |
1363 | StackSString m_sszMember; |
1364 | }; |
1365 | |
1366 | public: |
1367 | class CompiledQueries |
1368 | { |
1369 | public: |
1370 | CompiledQueries() { LIMITED_METHOD_CONTRACT; } |
1371 | |
1372 | public: |
1373 | BOOL Test(MethodDesc* pMethodDesc); |
1374 | BOOL Test(FieldDesc* pFieldDesc); |
1375 | BOOL Test(MethodTable* pMethodTable); |
1376 | |
1377 | private: |
1378 | friend class MdaQuery; |
1379 | |
1380 | private: |
1381 | CompiledQuery* AddQuery(); |
1382 | |
1383 | private: |
1384 | InlineSArray<CompiledQuery*, 10> m_queries; |
1385 | MdaFactory<CompiledQuery> m_factory; |
1386 | }; |
1387 | |
1388 | public: |
1389 | static void Compile(MdaXmlElement* pXmlFilter, CompiledQueries* pCompiledQueries); |
1390 | |
1391 | private: |
1392 | friend class ManagedDebuggingAssistants; |
1393 | |
1394 | private: |
1395 | class Compiler |
1396 | { |
1397 | private: |
1398 | friend class CompiledQuery; |
1399 | friend class MdaQuery; |
1400 | |
1401 | private: |
1402 | BOOL Compile(SString* sszQuery, CompiledQuery* pCompiledQuery); |
1403 | |
1404 | typedef enum |
1405 | { |
1406 | // |
1407 | // TOKENS |
1408 | // |
1409 | MdaFilterIdentifier = 0x0001, |
1410 | MdaFilterDot = 0x0002, |
1411 | MdaFilterPlus = 0x0004, |
1412 | MdaFilterAstrix = 0x0008, |
1413 | MdaFilterColon = 0x0010, |
1414 | MdaFilterEnd = 0x4000, |
1415 | } |
1416 | Token; |
1417 | |
1418 | // |
1419 | // LEXIFIER |
1420 | // |
1421 | private: |
1422 | Token LexAToken(); |
1423 | void NextToken() { WRAPPER_NO_CONTRACT; m_currentToken = LexAToken(); } |
1424 | BOOL TokenIs(Token token) { LIMITED_METHOD_CONTRACT; return !!(m_currentToken & token); } |
1425 | BOOL TokenIs(int token) { LIMITED_METHOD_CONTRACT; return TokenIs((Token)token); } |
1426 | LPCWSTR GetIdentifier() { WRAPPER_NO_CONTRACT; return m_identifier.GetUnicode(); } |
1427 | |
1428 | // |
1429 | // PRODUCTIONS |
1430 | // |
1431 | private: |
1432 | |
1433 | BOOL NAME(CompiledQuery* pAst); |
1434 | // '*' |
1435 | // id |
1436 | // id '.' NAME |
1437 | // id '+' NESTNAME |
1438 | // id ':' ':' MEMBERNAME |
1439 | |
1440 | BOOL NESTNAME(CompiledQuery* pAst); |
1441 | // id '+' NESTNAME |
1442 | // id ':' ':' MEMBERNAME |
1443 | |
1444 | BOOL MEMBERNAME(CompiledQuery* pAst); |
1445 | // '*' |
1446 | // id |
1447 | |
1448 | private: |
1449 | SString::CIterator m_itr; |
1450 | StackSString m_identifier; |
1451 | Token m_currentToken; |
1452 | }; |
1453 | }; |
1454 | |
1455 | |
1456 | // |
1457 | // MdaConfigFactory |
1458 | // |
1459 | class MdaConfigFactory : public IXMLNodeFactory |
1460 | { |
1461 | private: |
1462 | friend class ManagedDebuggingAssistants; |
1463 | |
1464 | private: |
1465 | static MdaXmlElement* ParseXmlStream(MdaXmlIndustry* pXmlIndustry, LPCWSTR szXmlStream); |
1466 | |
1467 | private: |
1468 | MdaConfigFactory(MdaXmlElement* pXmlRoot, BOOL bDeveloperSettings = FALSE) { WRAPPER_NO_CONTRACT; m_bParse = !bDeveloperSettings; m_pMdaXmlElement = NULL; m_stack.Push(pXmlRoot); } |
1469 | |
1470 | public: |
1471 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) { WRAPPER_NO_CONTRACT; return S_OK; } |
1472 | ULONG STDMETHODCALLTYPE AddRef() { WRAPPER_NO_CONTRACT; return 0; } |
1473 | ULONG STDMETHODCALLTYPE Release() { WRAPPER_NO_CONTRACT; return 0; } |
1474 | |
1475 | public: |
1476 | HRESULT STDMETHODCALLTYPE NotifyEvent( |
1477 | IXMLNodeSource* pSource, |
1478 | XML_NODEFACTORY_EVENT iEvt); |
1479 | |
1480 | HRESULT STDMETHODCALLTYPE BeginChildren( |
1481 | IXMLNodeSource* pSource, |
1482 | XML_NODE_INFO* pNodeInfo); |
1483 | |
1484 | HRESULT STDMETHODCALLTYPE EndChildren( |
1485 | IXMLNodeSource* pSource, |
1486 | BOOL fEmptyNode, |
1487 | XML_NODE_INFO* pNodeInfo); |
1488 | |
1489 | HRESULT STDMETHODCALLTYPE Error( |
1490 | IXMLNodeSource* pSource, |
1491 | HRESULT hrErrorCode, |
1492 | USHORT cNumRecs, |
1493 | XML_NODE_INFO** apNodeInfo); |
1494 | |
1495 | HRESULT STDMETHODCALLTYPE CreateNode( |
1496 | IXMLNodeSource* pSource, |
1497 | PVOID pNodeParent, |
1498 | USHORT cNumRecs, |
1499 | XML_NODE_INFO** apNodeInfo); |
1500 | |
1501 | private: |
1502 | BOOL m_bParse; |
1503 | MdaXmlElement* m_pMdaXmlElement; |
1504 | MdaStack<MdaXmlElement*> m_stack; |
1505 | }; |
1506 | |
1507 | #pragma warning(pop) |
1508 | |
1509 | #include "mda.inl" |
1510 | |
1511 | #endif |
1512 | #endif |
1513 | |
1514 | |