OLD | NEW |
| (Empty) |
1 // Copyright 2009 The Native Client Authors. All rights reserved. | |
2 // | |
3 // Use of this source code is governed by a BSD-style license that can | |
4 // | |
5 // be found in the LICENSE file. | |
6 | |
7 using System.Collections.Generic; | |
8 using System.Reflection; | |
9 using Microsoft.VisualStudio; | |
10 using Microsoft.VisualStudio.Debugger.Interop; | |
11 using System.Linq; | |
12 | |
13 namespace Google.MsAd7.BaseImpl { | |
14 namespace Ad7Enumerators { | |
15 | |
16 #region Base | |
17 | |
18 public class EnumeratorBase<TElement, TBase, TDerived> | |
19 where TDerived : EnumeratorBase<TElement, TBase, TDerived>, TBase | |
20 where TBase : class { | |
21 public EnumeratorBase(ICollection<TElement> collection) { | |
22 collection_ = collection; | |
23 enumerator_ = collection.GetEnumerator(); | |
24 } | |
25 | |
26 public ICollection<TElement> Collection { | |
27 get { return collection_; } | |
28 } | |
29 | |
30 #region Implementation of IEnumDebugTElements2 | |
31 | |
32 /// <summary> | |
33 /// Returns the next set of elements from the enumeration. | |
34 /// </summary> | |
35 /// <param name = "celt"> | |
36 /// [in] The number of elements to retrieve. | |
37 /// Also specifies the maximum size of the <paramref name = "rgelt" /> | |
38 /// array. | |
39 /// </param> | |
40 /// <param name = "rgelt"> | |
41 /// [in, out] Array of TInterface elements to be filled in. | |
42 /// </param> | |
43 /// <param name = "pceltFetched"> | |
44 /// [out] Returns the number of elements actually returned in rgelt. | |
45 /// </param> | |
46 /// <returns> | |
47 /// If successful, returns S_OK. Returns S_FALSE if fewer than the | |
48 /// requested number of elements could be returned; otherwise, returns | |
49 /// an error code | |
50 /// </returns> | |
51 public int Next(uint celt, TElement[] rgelt, ref uint pceltFetched) { | |
52 pceltFetched = 0; | |
53 for (uint i = 0; | |
54 i < celt && enumerator_.MoveNext(); | |
55 ++i) { | |
56 rgelt[i] = enumerator_.Current; | |
57 ++pceltFetched; | |
58 } | |
59 return (celt == pceltFetched) ? VSConstants.S_OK : VSConstants.S_FALSE; | |
60 } | |
61 | |
62 | |
63 /// <summary> | |
64 /// Skips over the specified number of elements. | |
65 /// </summary> | |
66 /// <param name = "celt">[in] Number of elements to skip.</param> | |
67 /// <returns> | |
68 /// If successful, returns S_OK. Returns S_FALSE if celt is greater than | |
69 /// the number of remaining elements; otherwise, returns an error code. | |
70 /// </returns> | |
71 public int Skip(uint celt) { | |
72 uint i; | |
73 for (i = 0; | |
74 i < celt && enumerator_.MoveNext(); | |
75 ++i) {} | |
76 return (i == celt) ? VSConstants.S_OK : VSConstants.S_FALSE; | |
77 } | |
78 | |
79 /// <summary> | |
80 /// Resets the enumeration to the first element. | |
81 /// </summary> | |
82 /// <returns> | |
83 /// If successful, returns S_OK; otherwise, returns an error code. | |
84 /// </returns> | |
85 public int Reset() { | |
86 enumerator_ = collection_.GetEnumerator(); | |
87 return VSConstants.S_OK; | |
88 } | |
89 | |
90 /// <summary> | |
91 /// Returns a copy of the current enumeration as a separate object. | |
92 /// </summary> | |
93 /// <param name = "ppEnum"> | |
94 /// [out] Returns a copy of this enumeration as a separate object. | |
95 /// </param> | |
96 /// <returns> | |
97 /// If successful, returns S_OK; otherwise, returns an error code. | |
98 /// </returns> | |
99 public int Clone(out TBase ppEnum) { | |
100 ConstructorInfo cons = | |
101 typeof (TDerived).GetConstructor(new[] {collection_.GetType()}); | |
102 ppEnum = cons.Invoke(new object[] {collection_}) as TBase; | |
103 | |
104 return VSConstants.S_OK; | |
105 } | |
106 | |
107 /// <summary> | |
108 /// </summary> | |
109 /// <param name = "pcelt"> | |
110 /// [out] Returns the number of elements in the enumeration. | |
111 /// </param> | |
112 /// <returns> | |
113 /// If successful, returns S_OK; otherwise, returns an error code. | |
114 /// </returns> | |
115 public int GetCount(out uint pcelt) { | |
116 pcelt = (uint) collection_.Count; | |
117 return VSConstants.S_OK; | |
118 } | |
119 | |
120 #endregion | |
121 | |
122 #region Private Implementation | |
123 | |
124 readonly ICollection<TElement> collection_; | |
125 IEnumerator<TElement> enumerator_; | |
126 | |
127 #endregion | |
128 } | |
129 | |
130 #endregion Base | |
131 | |
132 public class ErrorBreakpointEnumerator | |
133 : EnumeratorBase<IDebugErrorBreakpoint2, | |
134 IEnumDebugErrorBreakpoints2, | |
135 ErrorBreakpointEnumerator>, | |
136 IEnumDebugErrorBreakpoints2 { | |
137 public ErrorBreakpointEnumerator() | |
138 : base(new List<IDebugErrorBreakpoint2>()) {} | |
139 public ErrorBreakpointEnumerator(ICollection<IDebugErrorBreakpoint2> colle
ction) | |
140 :base(collection) {} | |
141 | |
142 /// <summary> | |
143 /// This function exists so the PendingBreakpoint can add itself to the er
rors in this | |
144 /// enumeration after BreakpointInfo generates them. | |
145 /// </summary> | |
146 public int PopulateBreakpoint(PendingBreakpoint breakpoint) { | |
147 int populated = VSConstants.S_FALSE; | |
148 if (Collection != null) { | |
149 foreach ( | |
150 ErrorBreakpoint assignable in | |
151 Collection.OfType<ErrorBreakpoint>()) { | |
152 assignable.PendingBreakpoint = breakpoint; | |
153 populated = VSConstants.S_OK; | |
154 } | |
155 } | |
156 return populated; | |
157 } | |
158 | |
159 public void Insert(IDebugErrorBreakpoint2 point) { | |
160 Collection.Add(point); | |
161 // Reset makes the underlying class get a new enumerator, which is neces
sary because the | |
162 // old one was just invalidated. | |
163 Reset(); | |
164 } | |
165 } | |
166 | |
167 public class ProgramEnumerator | |
168 : EnumeratorBase<IDebugProgram2, IEnumDebugPrograms2, ProgramEnumerator> | |
169 , | |
170 IEnumDebugPrograms2 { | |
171 public ProgramEnumerator(ICollection<IDebugProgram2> collection) | |
172 : base(collection) {} | |
173 } | |
174 | |
175 public class ModuleEnumerator | |
176 : EnumeratorBase<IDebugModule2, IEnumDebugModules2, ModuleEnumerator>, | |
177 IEnumDebugModules2 { | |
178 public ModuleEnumerator(ICollection<IDebugModule2> collection) | |
179 : base(collection) {} | |
180 } | |
181 | |
182 public class FrameInfoEnumerator | |
183 : EnumeratorBase<FRAMEINFO, IEnumDebugFrameInfo2, FrameInfoEnumerator>, | |
184 IEnumDebugFrameInfo2 { | |
185 public FrameInfoEnumerator(ICollection<FRAMEINFO> collection) | |
186 : base(collection) {} | |
187 } | |
188 | |
189 public class ThreadEnumerator | |
190 : EnumeratorBase<IDebugThread2, IEnumDebugThreads2, ThreadEnumerator>, | |
191 IEnumDebugThreads2 { | |
192 public ThreadEnumerator(ICollection<IDebugThread2> collection) | |
193 : base(collection) {} | |
194 } | |
195 | |
196 public class PropertyEnumerator | |
197 : EnumeratorBase | |
198 <DEBUG_PROPERTY_INFO, IEnumDebugPropertyInfo2, PropertyEnumerator>
, | |
199 IEnumDebugPropertyInfo2 { | |
200 public PropertyEnumerator(ICollection<DEBUG_PROPERTY_INFO> collection) | |
201 : base(collection) {} | |
202 | |
203 // The PIA definition of this interface has a typo, and Next is defined wi
th | |
204 // an out param instead of a ref param. This little shim fixes that. | |
205 | |
206 #region IEnumDebugPropertyInfo2 Members | |
207 | |
208 public int Next(uint celt, | |
209 DEBUG_PROPERTY_INFO[] rgelt, | |
210 out uint pceltFetched) { | |
211 uint n = 0; | |
212 int result = base.Next(celt, rgelt, ref n); | |
213 pceltFetched = n; | |
214 return result; | |
215 } | |
216 | |
217 #endregion | |
218 } | |
219 | |
220 public class CodeContextEnumerator | |
221 : EnumeratorBase | |
222 <IDebugCodeContext2, IEnumDebugCodeContexts2, | |
223 CodeContextEnumerator>, | |
224 IEnumDebugCodeContexts2 { | |
225 public CodeContextEnumerator(ICollection<IDebugCodeContext2> collection) | |
226 : base(collection) {} | |
227 } | |
228 | |
229 public class PortEnumerator | |
230 : EnumeratorBase<IDebugPort2, IEnumDebugPorts2, PortEnumerator>, | |
231 IEnumDebugPorts2 { | |
232 public PortEnumerator(ICollection<IDebugPort2> collection) | |
233 : base(collection) { } | |
234 } | |
235 | |
236 public class ProcessEnumerator | |
237 : EnumeratorBase | |
238 <IDebugProcess2, IEnumDebugProcesses2, ProcessEnumerator>, | |
239 IEnumDebugProcesses2 { | |
240 public ProcessEnumerator(ICollection<IDebugProcess2> collection) | |
241 : base(collection) {} | |
242 } | |
243 } | |
244 } | |
OLD | NEW |