/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Debugger.Interop;
namespace QtVsTools.Qml.Debug.AD7
{
///
/// Abstraction of AD7 enum interfaces, e.g. IEnumDebugPrograms2
/// (cf. https://docs.microsoft.com/en-us/visualstudio/extensibility/debugger/reference/ienumdebugprograms2)
///
///
class Enum
where TEnum : Enum, new()
where IEnum : class
{
int index;
IList list;
public static TEnum Create(IEnumerable data)
{
return new TEnum
{
index = 0,
list = new List(data)
};
}
public static TEnum Create(T singleElement)
{
return new TEnum
{
index = 0,
list = new List() { singleElement }
};
}
public static TEnum Create()
{
return new TEnum
{
index = 0,
list = new List()
};
}
protected Enum()
{ }
///
/// Returns the next set of elements from the enumeration.
///
/// The number of elements to retrieve.
///
/// Collection of retrieved elements.
///
public IEnumerable Next(uint numElems)
{
int oldIndex = index;
int maxIndex = Math.Min(list.Count, oldIndex + (int)numElems);
for (; index < maxIndex; ++index)
yield return list[index];
}
///
/// Returns the next set of elements from the enumeration.
///
///
/// The number of elements to retrieve.
///
///
/// Array of elements to be filled in.
///
///
/// Returns the number of elements actually returned in elems.
///
///
/// If successful, returns S_OK. Returns S_FALSE if fewer than the requested number of
/// elements could be returned.
///
public int Next(uint numElems, T[] elems, ref uint numElemsFetched)
{
var next = Next(numElems).ToArray();
Array.Copy(next, elems, next.Length);
numElemsFetched = (uint)next.Length;
if (numElemsFetched < numElems)
return VSConstants.S_FALSE;
return VSConstants.S_OK;
}
///
/// Skips over the specified number of elements.
///
/// Number of elements to skip.
///
/// If successful, returns S_OK. Returns S_FALSE if numElems is greater than the number of
/// remaining elements; otherwise, returns an error code.
///
///
/// If numElems specifies a value greater than the number of remaining elements, the
/// enumeration is set to the end and S_FALSE is returned.
///
public int Skip(uint numElems)
{
if ((ulong)index + numElems > Int32.MaxValue)
return VSConstants.E_INVALIDARG;
if (index + numElems > list.Count) {
index = list.Count;
return VSConstants.S_FALSE;
}
index += (int)numElems;
return VSConstants.S_OK;
}
///
/// Resets the enumeration to the first element.
///
///
/// If successful, returns S_OK; otherwise, returns an error code.
///
public int Reset()
{
index = 0;
return VSConstants.S_OK;
}
///
/// Returns the number of elements in the enumeration.
///
/// Returns the number of elements in the enumeration.
///
/// If successful, returns S_OK; otherwise, returns an error code.
///
public int GetCount(out uint numElems)
{
numElems = (uint)list.Count;
return VSConstants.S_OK;
}
///
/// Returns a copy of the current enumeration as a separate object.
///
/// Returns the clone of this enumeration.
///
/// If successful, returns S_OK; otherwise, returns an error code.
///
///
/// The copy of the enumeration has the same state as the original at the time this method
/// is called. However, the copy's and the original's states are separate and can be
/// changed individually.
///
public int Clone(out IEnum clonedEnum)
{
var clone = new TEnum();
clone.index = index;
clone.list = new List(list);
clonedEnum = clone as IEnum;
return VSConstants.S_OK;
}
}
class ProgramEnum :
Enum,
IEnumDebugPrograms2
{ }
class FrameInfoEnum :
Enum,
IEnumDebugFrameInfo2
{ }
class ThreadEnum :
Enum,
IEnumDebugThreads2
{ }
class ModuleEnum :
Enum,
IEnumDebugModules2
{ }
class CodeContextEnum :
Enum,
IEnumDebugCodeContexts2
{ }
class BoundBreakpointsEnum :
Enum,
IEnumDebugBoundBreakpoints2
{ }
class ErrorBreakpointsEnum :
Enum,
IEnumDebugErrorBreakpoints2
{ }
class PropertyEnum :
Enum,
IEnumDebugPropertyInfo2
{
public int Next(uint celt, DEBUG_PROPERTY_INFO[] rgelt, out uint pceltFetched)
{
pceltFetched = 0;
return Next(celt, rgelt, ref pceltFetched);
}
}
}