<commit_before>// Qt
#include <QStandardItem>

// AMDTBaseTools
#include <AMDTBaseTools/Include/AMDTDefinitions.h>

// local files
#include <AMDTGpuProfiling/gpObjectModels.h>

ObjTreeModel::ObjTreeModel(QDomDocument document, QObject* parent)
    : QStandardItemModel(parent), m_DomDoc(document)
{
    m_rootItem = this->invisibleRootItem();

    refreshTree();
}

ObjTreeModel::~ObjTreeModel()
{

}

void ObjTreeModel::setIncludeDestroyed(int iIncludeDestroyed)
{
    m_iIncludeDestroyed = iIncludeDestroyed;
    refreshTree();
}

void ObjTreeModel::setGroupDestroyed(int iGroupDestroyed)
{
    m_iGroupDestroyed = iGroupDestroyed;
    refreshTree();
}

void ObjTreeModel::refreshTree()
{
    // get list of Devices
    QDomNodeList listDevices = m_DomDoc.elementsByTagName("Device");

    // remove nodes
    m_rootItem->removeRows(0, m_rootItem->rowCount());

    // get list of DX objects
    for (int iDevIdx = 0; iDevIdx < listDevices.count(); iDevIdx++)
    {
        QString strItem = "", strCheck = "";
        QStandardItem* DeviceItem;

        strItem.append(listDevices.at(iDevIdx).nodeName());
        strItem.append(" - ");
        // appending pointer string
        strItem.append(listDevices.at(iDevIdx).attributes().item(0).nodeValue());

        DeviceItem = new QStandardItem(strItem);

        m_rootItem->appendRow(DeviceItem);

        // getting the dx elements
        QDomNode nodeElement = listDevices.at(iDevIdx).firstChildElement();

        while (!nodeElement.isNull())
        {
            QStandardItem* dxObjItem, *newObjItem;
            QStringList ptrStrList;
            bool bDestroyed;

            strCheck = nodeElement.nodeName();
            strCheck = nodeElement.toElement().text();

            dxObjItem = new QStandardItem(nodeElement.nodeName());
            DeviceItem->appendRow(dxObjItem);

            ptrStrList = nodeElement.toElement().text().split(',', QString::SkipEmptyParts);

            for (int iPtrIdx = 0; iPtrIdx < ptrStrList.count(); iPtrIdx++)
            {
                // search for "|d", these are destroyed
                bDestroyed = (ptrStrList[iPtrIdx].right(2).compare("|d") == 0);

                if (bDestroyed)
                {
                    // remove "|d"
                    ptrStrList[iPtrIdx] = ptrStrList[iPtrIdx].left(ptrStrList[iPtrIdx].length() - 2);
                }

                if ((Qt::Unchecked != m_iIncludeDestroyed) || !bDestroyed)
                {
                    newObjItem = new QStandardItem(ptrStrList[iPtrIdx]);

                    if (bDestroyed)
                    {
                        QFont myFont = newObjItem->font();
                        myFont.setStrikeOut(true);
                        newObjItem->setFont(myFont);
                    }

                    dxObjItem->appendRow(newObjItem);
                }
            }

            nodeElement = nodeElement.nextSiblingElement();
        }
    }
}

QVariant ObjTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    GT_UNREFERENCED_PARAMETER(section);
    GT_UNREFERENCED_PARAMETER(orientation);
    GT_UNREFERENCED_PARAMETER(role);

    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
    {
        return tr("AMD Graphics");
    }

    return QVariant();
}

void ObjTreeModel::setDomDoc(QDomDocument document)
{
    m_DomDoc = document;

    refreshTree();
}

// ObjDatabaseModel begin
ObjDatabaseModel::ObjDatabaseModel(QDomDocument document, QObject* parent)
    : QStandardItemModel(parent), m_DomDoc(document)
{
    m_rootItem = this->invisibleRootItem();

    // get list of Devices
    QDomNodeList listInfos = m_DomDoc.elementsByTagName("CreateInfo");

    if (listInfos.count() > 0)
    {
        DisplayObjectNode(listInfos.at(0).firstChildElement());
    }
}

// slot
void ObjDatabaseModel::dBaseObjSelected(const QString strObjectSelected)
{
    DisplayObject(strObjectSelected);
}

// show object details id'ed by Handle
void ObjDatabaseModel::DisplayObject(QString strHandle)
{
    QString strItem = "", strCheck = "";

    // search for dom object with correct handle
    // get list of Devices
    QDomNodeList listInfos = m_DomDoc.elementsByTagName("CreateInfo");

    // get list of DX objects
    for (int iInfoIdx = 0; iInfoIdx < listInfos.count(); iInfoIdx++)
    {
        // sample string for nodeValue() "0x000000DA83E60200"
        strCheck = listInfos.at(iInfoIdx).attributes().item(0).nodeValue();

        if (0 == strHandle.compare(strCheck, Qt::CaseInsensitive))
        {
            // Object found
            DisplayObjectNode(listInfos.at(iInfoIdx).firstChildElement());
        }
    }
}

// show specified XML obj node, this is the node after info handle, i.e. the node of "ID3D12RootSignature", "ID3D12ComittedResource", "ID3D12CommandList"
void ObjDatabaseModel::DisplayObjectNode(QDomNode domObjectNode)
{
    //    domObjectNode contains the CreateInfo node
    QString strName = "", strCheck = "", strValue = "";
    QStandardItem* pNextTreeItem;

    // getting the dx elements
    m_rootItem->removeRows(0, m_rootItem->rowCount());
    pNextTreeItem = m_rootItem;

    // 1st element is the object type label, only one of these
    strName = domObjectNode.nodeName();
    strCheck = domObjectNode.toElement().text();

    // top node, Object type string,
    QDomNode nodeElement = domObjectNode.firstChildElement();

    // send object type to edit box
    emit(ObjDisplayed(domObjectNode.nodeName()));

    while (!nodeElement.isNull())
    {
        QList<QStandardItem*> rowItems;

        strName = nodeElement.nodeName();
        strCheck = nodeElement.toElement().text();

        if (nodeElement.hasAttributes())
        {
            strValue = nodeElement.attributes().item(0).nodeValue();
            rowItems << new QStandardItem(nodeElement.attributes().item(0).nodeValue());

            if (nodeElement.hasChildNodes() && nodeElement.firstChild().isText())
            {
                strCheck = nodeElement.toElement().text();
                rowItems << new QStandardItem(nodeElement.toElement().text());
            }
            else
            {
                strName = nodeElement.nodeName();
                rowItems << new QStandardItem(nodeElement.nodeName());
            }

            pNextTreeItem->appendRow(rowItems);

            // recursive function to fill table
            if (nodeElement.firstChild().childNodes().count() > 0)
            {
                FillTree(rowItems.first(), nodeElement);
            }
        }
        else
        {
            // TODO invalid node assert
        }

        nodeElement = nodeElement.nextSiblingElement();
    }
}

// recursive function to build Object Database tree
void ObjDatabaseModel::FillTree(QStandardItem* pNextTreeItem, QDomNode elementNode)
{
    GT_UNREFERENCED_PARAMETER(pNextTreeItem);
    GT_UNREFERENCED_PARAMETER(elementNode);

    QString strName = "", strCheck = "", strValue = "";
    QDomNode nodeElement = elementNode.firstChildElement();

    strCheck = nodeElement.nodeName();
    strCheck = nodeElement.toElement().text();

    while (!nodeElement.isNull())
    {
        QList<QStandardItem*> rowItems;

        strName = nodeElement.nodeName();
        strCheck = nodeElement.toElement().text();

        if (nodeElement.hasAttributes())
        {
            strValue = nodeElement.attributes().item(0).nodeValue();
            rowItems << new QStandardItem(nodeElement.attributes().item(0).nodeValue());

            if (nodeElement.hasChildNodes() && nodeElement.firstChild().isText())
            {
                strCheck = nodeElement.toElement().text();
                rowItems << new QStandardItem(nodeElement.toElement().text());
            }
            else
            {
                strName = nodeElement.nodeName();
                rowItems << new QStandardItem(nodeElement.nodeName());
            }

            pNextTreeItem->appendRow(rowItems);

            // recursive function to fill table
            if (nodeElement.childNodes().count() > 0)
            {
                FillTree(rowItems.first(), nodeElement);
            }
        }
        else
        {
            // TODO invalid node assert
        }

        nodeElement = nodeElement.nextSiblingElement();
    }

}

ObjDatabaseModel::~ObjDatabaseModel()
{

}

QVariant ObjDatabaseModel::headerData(int section, Qt::Orientation orientation,
                                      int role) const
{
    GT_UNREFERENCED_PARAMETER(section);
    GT_UNREFERENCED_PARAMETER(orientation);
    GT_UNREFERENCED_PARAMETER(role);

    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
    {
        switch (section)
        {
            case 0:
                return tr("Description");

            case 1:
                return tr("Data");

            default:
                return QVariant();
        }
    }

    return QVariant();
}
<commit_msg>Removed unnessessary macros<commit_after>// Qt
#include <QStandardItem>

// AMDTBaseTools
#include <AMDTBaseTools/Include/AMDTDefinitions.h>

// local files
#include <AMDTGpuProfiling/gpObjectModels.h>

ObjTreeModel::ObjTreeModel(QDomDocument document, QObject* parent)
    : QStandardItemModel(parent), m_DomDoc(document)
{
    m_rootItem = this->invisibleRootItem();

    refreshTree();
}

ObjTreeModel::~ObjTreeModel()
{

}

void ObjTreeModel::setIncludeDestroyed(int iIncludeDestroyed)
{
    m_iIncludeDestroyed = iIncludeDestroyed;
    refreshTree();
}

void ObjTreeModel::setGroupDestroyed(int iGroupDestroyed)
{
    m_iGroupDestroyed = iGroupDestroyed;
    refreshTree();
}

void ObjTreeModel::refreshTree()
{
    // get list of Devices
    QDomNodeList listDevices = m_DomDoc.elementsByTagName("Device");

    // remove nodes
    m_rootItem->removeRows(0, m_rootItem->rowCount());

    // get list of DX objects
    for (int iDevIdx = 0; iDevIdx < listDevices.count(); iDevIdx++)
    {
        QString strItem = "", strCheck = "";
        QStandardItem* DeviceItem;

        strItem.append(listDevices.at(iDevIdx).nodeName());
        strItem.append(" - ");
        // appending pointer string
        strItem.append(listDevices.at(iDevIdx).attributes().item(0).nodeValue());

        DeviceItem = new QStandardItem(strItem);

        m_rootItem->appendRow(DeviceItem);

        // getting the dx elements
        QDomNode nodeElement = listDevices.at(iDevIdx).firstChildElement();

        while (!nodeElement.isNull())
        {
            QStandardItem* dxObjItem, *newObjItem;
            QStringList ptrStrList;
            bool bDestroyed;

            strCheck = nodeElement.nodeName();
            strCheck = nodeElement.toElement().text();

            dxObjItem = new QStandardItem(nodeElement.nodeName());
            DeviceItem->appendRow(dxObjItem);

            ptrStrList = nodeElement.toElement().text().split(',', QString::SkipEmptyParts);

            for (int iPtrIdx = 0; iPtrIdx < ptrStrList.count(); iPtrIdx++)
            {
                // search for "|d", these are destroyed
                bDestroyed = (ptrStrList[iPtrIdx].right(2).compare("|d") == 0);

                if (bDestroyed)
                {
                    // remove "|d"
                    ptrStrList[iPtrIdx] = ptrStrList[iPtrIdx].left(ptrStrList[iPtrIdx].length() - 2);
                }

                if ((Qt::Unchecked != m_iIncludeDestroyed) || !bDestroyed)
                {
                    newObjItem = new QStandardItem(ptrStrList[iPtrIdx]);

                    if (bDestroyed)
                    {
                        QFont myFont = newObjItem->font();
                        myFont.setStrikeOut(true);
                        newObjItem->setFont(myFont);
                    }

                    dxObjItem->appendRow(newObjItem);
                }
            }

            nodeElement = nodeElement.nextSiblingElement();
        }
    }
}

QVariant ObjTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    GT_UNREFERENCED_PARAMETER(section);
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
    {
        return tr("AMD Graphics");
    }

    return QVariant();
}

void ObjTreeModel::setDomDoc(QDomDocument document)
{
    m_DomDoc = document;

    refreshTree();
}

// ObjDatabaseModel begin
ObjDatabaseModel::ObjDatabaseModel(QDomDocument document, QObject* parent)
    : QStandardItemModel(parent), m_DomDoc(document)
{
    m_rootItem = this->invisibleRootItem();

    // get list of Devices
    QDomNodeList listInfos = m_DomDoc.elementsByTagName("CreateInfo");

    if (listInfos.count() > 0)
    {
        DisplayObjectNode(listInfos.at(0).firstChildElement());
    }
}

// slot
void ObjDatabaseModel::dBaseObjSelected(const QString strObjectSelected)
{
    DisplayObject(strObjectSelected);
}

// show object details id'ed by Handle
void ObjDatabaseModel::DisplayObject(QString strHandle)
{
    QString strItem = "", strCheck = "";

    // search for dom object with correct handle
    // get list of Devices
    QDomNodeList listInfos = m_DomDoc.elementsByTagName("CreateInfo");

    // get list of DX objects
    for (int iInfoIdx = 0; iInfoIdx < listInfos.count(); iInfoIdx++)
    {
        // sample string for nodeValue() "0x000000DA83E60200"
        strCheck = listInfos.at(iInfoIdx).attributes().item(0).nodeValue();

        if (0 == strHandle.compare(strCheck, Qt::CaseInsensitive))
        {
            // Object found
            DisplayObjectNode(listInfos.at(iInfoIdx).firstChildElement());
        }
    }
}

// show specified XML obj node, this is the node after info handle, i.e. the node of "ID3D12RootSignature", "ID3D12ComittedResource", "ID3D12CommandList"
void ObjDatabaseModel::DisplayObjectNode(QDomNode domObjectNode)
{
    //    domObjectNode contains the CreateInfo node
    QString strName = "", strCheck = "", strValue = "";
    QStandardItem* pNextTreeItem;

    // getting the dx elements
    m_rootItem->removeRows(0, m_rootItem->rowCount());
    pNextTreeItem = m_rootItem;

    // 1st element is the object type label, only one of these
    strName = domObjectNode.nodeName();
    strCheck = domObjectNode.toElement().text();

    // top node, Object type string,
    QDomNode nodeElement = domObjectNode.firstChildElement();

    // send object type to edit box
    emit(ObjDisplayed(domObjectNode.nodeName()));

    while (!nodeElement.isNull())
    {
        QList<QStandardItem*> rowItems;

        strName = nodeElement.nodeName();
        strCheck = nodeElement.toElement().text();

        if (nodeElement.hasAttributes())
        {
            strValue = nodeElement.attributes().item(0).nodeValue();
            rowItems << new QStandardItem(nodeElement.attributes().item(0).nodeValue());

            if (nodeElement.hasChildNodes() && nodeElement.firstChild().isText())
            {
                strCheck = nodeElement.toElement().text();
                rowItems << new QStandardItem(nodeElement.toElement().text());
            }
            else
            {
                strName = nodeElement.nodeName();
                rowItems << new QStandardItem(nodeElement.nodeName());
            }

            pNextTreeItem->appendRow(rowItems);

            // recursive function to fill table
            if (nodeElement.firstChild().childNodes().count() > 0)
            {
                FillTree(rowItems.first(), nodeElement);
            }
        }
        else
        {
            // TODO invalid node assert
        }

        nodeElement = nodeElement.nextSiblingElement();
    }
}

// recursive function to build Object Database tree
void ObjDatabaseModel::FillTree(QStandardItem* pNextTreeItem, QDomNode elementNode)
{
    GT_UNREFERENCED_PARAMETER(pNextTreeItem);
    GT_UNREFERENCED_PARAMETER(elementNode);

    QString strName = "", strCheck = "", strValue = "";
    QDomNode nodeElement = elementNode.firstChildElement();

    strCheck = nodeElement.nodeName();
    strCheck = nodeElement.toElement().text();

    while (!nodeElement.isNull())
    {
        QList<QStandardItem*> rowItems;

        strName = nodeElement.nodeName();
        strCheck = nodeElement.toElement().text();

        if (nodeElement.hasAttributes())
        {
            strValue = nodeElement.attributes().item(0).nodeValue();
            rowItems << new QStandardItem(nodeElement.attributes().item(0).nodeValue());

            if (nodeElement.hasChildNodes() && nodeElement.firstChild().isText())
            {
                strCheck = nodeElement.toElement().text();
                rowItems << new QStandardItem(nodeElement.toElement().text());
            }
            else
            {
                strName = nodeElement.nodeName();
                rowItems << new QStandardItem(nodeElement.nodeName());
            }

            pNextTreeItem->appendRow(rowItems);

            // recursive function to fill table
            if (nodeElement.childNodes().count() > 0)
            {
                FillTree(rowItems.first(), nodeElement);
            }
        }
        else
        {
            // TODO invalid node assert
        }

        nodeElement = nodeElement.nextSiblingElement();
    }

}

ObjDatabaseModel::~ObjDatabaseModel()
{

}

QVariant ObjDatabaseModel::headerData(int section, Qt::Orientation orientation,
                                      int role) const
{
    GT_UNREFERENCED_PARAMETER(section);
    GT_UNREFERENCED_PARAMETER(orientation);
    GT_UNREFERENCED_PARAMETER(role);

    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
    {
        switch (section)
        {
            case 0:
                return tr("Description");

            case 1:
                return tr("Data");

            default:
                return QVariant();
        }
    }

    return QVariant();
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 */

#ifndef __ARCH_ARM_LINUX_ATAG_HH__
#define __ARCH_ARM_LINUX_ATAG_HH__

#include <cstring>
#include <string>

#include "base/types.hh"

enum {
    CoreTag   = 0x54410001,
    MemTag    = 0x54410002,
    RevTag    = 0x54410007,
    SerialTag = 0x54410006,
    CmdTag    = 0x54410009,
    NoneTag   = 0x00000000,
};

class AtagHeader
{
  protected:
    uint32_t *storage;
    uint32_t _size;

  public:
    /** Tag (normally starts with 'T''A' and 16 bits of number */
    virtual uint32_t tag() = 0;
    /** If the header should be 0 size */
    virtual bool null() { return false; }

    uint32_t size() const { return _size; }

    AtagHeader(uint32_t s)
        : _size(s)
    {
        storage = new uint32_t[size()];
    }

    virtual ~AtagHeader()
    {
        delete[] storage;
    }

    uint32_t copyOut(uint8_t *p)
    {
        storage[0] = null() ? 0 : size();
        storage[1] = tag();
        memcpy(p, storage, size() << 2);
        return size() << 2;
    }
};

class AtagCore : public AtagHeader
{
  public:
    static const uint32_t Size = 5;
    uint32_t tag() { return CoreTag; }

    void flags(uint32_t i) { storage[2] = i; }
    void pagesize(uint32_t i) { storage[3] = i; }
    void rootdev(uint32_t i) { storage[4] = i; }
    AtagCore()
        : AtagHeader(Size)
    {}
};

class AtagMem : public AtagHeader
{
  public:
    static const uint32_t Size = 4;
    uint32_t tag() { return MemTag; }

    void memSize(uint32_t i) { storage[2] = i; }
    void memStart(uint32_t i) { storage[3] = i; }
    AtagMem()
        : AtagHeader(Size)
    {}
};

class AtagRev : public AtagHeader
{
  public:
    static const uint32_t Size = 3;
    uint32_t tag() { return RevTag; }

    void rev(uint32_t i) { storage[2] = i; }
    AtagRev()
        : AtagHeader(Size)
    {}
};

class AtagSerial : public AtagHeader
{
  public:
    static const uint32_t Size = 4;
    uint32_t tag() { return SerialTag; }

    void sn(uint64_t i) { storage[2] = (uint32_t)i; storage[3] = i >> 32; }
    AtagSerial()
        : AtagHeader(Size)
    {}
};

class AtagCmdline : public AtagHeader
{
  public:
    static const uint32_t Size = 3;
    uint32_t tag() { return CmdTag; }

    void cmdline(const std::string &s)
    {
        // Add one for null terminator
        int len = s.length() + 1;

        // 2 + ceiling(len/4)
        _size = 2 + ((len + 3) >> 2);

        delete[] storage;
        storage = new uint32_t[size()];

        strcpy((char*)&storage[2] , s.c_str());
    }
    AtagCmdline()
        : AtagHeader(Size)
    {}
};

class AtagNone : public AtagHeader
{
  public:
    static const uint32_t Size = 2;
    virtual bool null() { return true; }
    uint32_t tag() { return NoneTag; }
    AtagNone()
        : AtagHeader(Size)
    {}
};
/*
//
// example ARM Linux bootloader code
// this example is distributed under the BSD licence
// Code taken from http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html
///

// list of possible tags
#define ATAG_NONE       0x00000000
#define ATAG_CORE       0x54410001
#define ATAG_MEM        0x54410002
#define ATAG_VIDEOTEXT  0x54410003
#define ATAG_RAMDISK    0x54410004
#define ATAG_INITRD2    0x54420005
#define ATAG_SERIAL     0x54410006
#define ATAG_REVISION   0x54410007
#define ATAG_VIDEOLFB   0x54410008
#define ATAG_CMDLINE    0x54410009

// structures for each atag
struct atag_header {
        u32 size; // length of tag in words including this header
        u32 tag;  // tag type
};

struct atag_core {
        u32 flags;
        u32 pagesize;
        u32 rootdev;
};

struct atag_mem {
        u32     size;
        u32     start;
};

struct atag_videotext {
        u8              x;
        u8              y;
        u16             video_page;
        u8              video_mode;
        u8              video_cols;
        u16             video_ega_bx;
        u8              video_lines;
        u8              video_isvga;
        u16             video_points;
};

struct atag_ramdisk {
        u32 flags;
        u32 size;
        u32 start;
};

struct atag_initrd2 {
        u32 start;
        u32 size;
};

struct atag_serialnr {
        u32 low;
        u32 high;
};

struct atag_revision {
        u32 rev;
};

struct atag_videolfb {
        u16             lfb_width;
        u16             lfb_height;
        u16             lfb_depth;
        u16             lfb_linelength;
        u32             lfb_base;
        u32             lfb_size;
        u8              red_size;
        u8              red_pos;
        u8              green_size;
        u8              green_pos;
        u8              blue_size;
        u8              blue_pos;
        u8              rsvd_size;
        u8              rsvd_pos;
};

struct atag_cmdline {
        char    cmdline[1];
};

struct atag {
        struct atag_header hdr;
        union {
                struct atag_core         core;
                struct atag_mem          mem;
                struct atag_videotext    videotext;
                struct atag_ramdisk      ramdisk;
                struct atag_initrd2      initrd2;
                struct atag_serialnr     serialnr;
                struct atag_revision     revision;
                struct atag_videolfb     videolfb;
                struct atag_cmdline      cmdline;
        } u;
};
*/

#endif // __ARCH_ARM_LINUX_ATAG_HH__
<commit_msg>ARM: Fix valgrind reported error on O3 that was causing minor stats changes.<commit_after>/*
 * Copyright (c) 2010 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 */

#ifndef __ARCH_ARM_LINUX_ATAG_HH__
#define __ARCH_ARM_LINUX_ATAG_HH__

#include <cstring>
#include <string>

#include "base/types.hh"

enum {
    CoreTag   = 0x54410001,
    MemTag    = 0x54410002,
    RevTag    = 0x54410007,
    SerialTag = 0x54410006,
    CmdTag    = 0x54410009,
    NoneTag   = 0x00000000,
};

class AtagHeader
{
  protected:
    uint32_t *storage;
    uint32_t _size;

  public:
    /** Tag (normally starts with 'T''A' and 16 bits of number */
    virtual uint32_t tag() = 0;
    /** If the header should be 0 size */
    virtual bool null() { return false; }

    uint32_t size() const { return _size; }

    AtagHeader(uint32_t s)
        : _size(s)
    {
        storage = new uint32_t[size()];
    }

    virtual ~AtagHeader()
    {
        delete[] storage;
    }

    uint32_t copyOut(uint8_t *p)
    {
        storage[0] = null() ? 0 : size();
        storage[1] = tag();
        memcpy(p, storage, size() << 2);
        return size() << 2;
    }
};

class AtagCore : public AtagHeader
{
  public:
    static const uint32_t Size = 5;
    uint32_t tag() { return CoreTag; }

    void flags(uint32_t i) { storage[2] = i; }
    void pagesize(uint32_t i) { storage[3] = i; }
    void rootdev(uint32_t i) { storage[4] = i; }
    AtagCore()
        : AtagHeader(Size)
    {}
};

class AtagMem : public AtagHeader
{
  public:
    static const uint32_t Size = 4;
    uint32_t tag() { return MemTag; }

    void memSize(uint32_t i) { storage[2] = i; }
    void memStart(uint32_t i) { storage[3] = i; }
    AtagMem()
        : AtagHeader(Size)
    {}
};

class AtagRev : public AtagHeader
{
  public:
    static const uint32_t Size = 3;
    uint32_t tag() { return RevTag; }

    void rev(uint32_t i) { storage[2] = i; }
    AtagRev()
        : AtagHeader(Size)
    {}
};

class AtagSerial : public AtagHeader
{
  public:
    static const uint32_t Size = 4;
    uint32_t tag() { return SerialTag; }

    void sn(uint64_t i) { storage[2] = (uint32_t)i; storage[3] = i >> 32; }
    AtagSerial()
        : AtagHeader(Size)
    {}
};

class AtagCmdline : public AtagHeader
{
  public:
    static const uint32_t Size = 3;
    uint32_t tag() { return CmdTag; }

    void cmdline(const std::string &s)
    {
        // Add one for null terminator
        int len = s.length() + 1;

        // 2 + ceiling(len/4)
        _size = 2 + ((len + 3) >> 2);

        delete[] storage;
        storage = new uint32_t[size()];
        // Initialize the last byte of memory here beacuse it might be slightly
        // longer than needed and mis-speculation of the NULL in the O3 CPU can
        // change stats ever so slightly when that happens.
        storage[size() - 1] = 0;
        strcpy((char*)&storage[2] , s.c_str());
    }
    AtagCmdline()
        : AtagHeader(Size)
    {}
};

class AtagNone : public AtagHeader
{
  public:
    static const uint32_t Size = 2;
    virtual bool null() { return true; }
    uint32_t tag() { return NoneTag; }
    AtagNone()
        : AtagHeader(Size)
    {}
};
/*
//
// example ARM Linux bootloader code
// this example is distributed under the BSD licence
// Code taken from http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html
///

// list of possible tags
#define ATAG_NONE       0x00000000
#define ATAG_CORE       0x54410001
#define ATAG_MEM        0x54410002
#define ATAG_VIDEOTEXT  0x54410003
#define ATAG_RAMDISK    0x54410004
#define ATAG_INITRD2    0x54420005
#define ATAG_SERIAL     0x54410006
#define ATAG_REVISION   0x54410007
#define ATAG_VIDEOLFB   0x54410008
#define ATAG_CMDLINE    0x54410009

// structures for each atag
struct atag_header {
        u32 size; // length of tag in words including this header
        u32 tag;  // tag type
};

struct atag_core {
        u32 flags;
        u32 pagesize;
        u32 rootdev;
};

struct atag_mem {
        u32     size;
        u32     start;
};

struct atag_videotext {
        u8              x;
        u8              y;
        u16             video_page;
        u8              video_mode;
        u8              video_cols;
        u16             video_ega_bx;
        u8              video_lines;
        u8              video_isvga;
        u16             video_points;
};

struct atag_ramdisk {
        u32 flags;
        u32 size;
        u32 start;
};

struct atag_initrd2 {
        u32 start;
        u32 size;
};

struct atag_serialnr {
        u32 low;
        u32 high;
};

struct atag_revision {
        u32 rev;
};

struct atag_videolfb {
        u16             lfb_width;
        u16             lfb_height;
        u16             lfb_depth;
        u16             lfb_linelength;
        u32             lfb_base;
        u32             lfb_size;
        u8              red_size;
        u8              red_pos;
        u8              green_size;
        u8              green_pos;
        u8              blue_size;
        u8              blue_pos;
        u8              rsvd_size;
        u8              rsvd_pos;
};

struct atag_cmdline {
        char    cmdline[1];
};

struct atag {
        struct atag_header hdr;
        union {
                struct atag_core         core;
                struct atag_mem          mem;
                struct atag_videotext    videotext;
                struct atag_ramdisk      ramdisk;
                struct atag_initrd2      initrd2;
                struct atag_serialnr     serialnr;
                struct atag_revision     revision;
                struct atag_videolfb     videolfb;
                struct atag_cmdline      cmdline;
        } u;
};
*/

#endif // __ARCH_ARM_LINUX_ATAG_HH__
<|endoftext|>


<commit_before>/*
 * Copyright 2010 Norman Heino <norman.heino@gmail.com>
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include <node.h>

#include "parser.h"
#include "serializer.h"

using namespace v8;
using namespace node;

/* extern "C" to prevent name mangling */
extern "C" void init(Handle<Object> target) {
  NODE_SET_METHOD(target, "newParser", Parser::Initialize);
  NODE_SET_METHOD(target, "newSerializer", Serializer::Initialize);
}
<commit_msg>Add NODE_MODULE definition.<commit_after>/*
 * Copyright 2010 Norman Heino <norman.heino@gmail.com>
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include <node.h>

#include "parser.h"
#include "serializer.h"

using namespace v8;
using namespace node;

void Initialize(Handle<Object> target) {
  NODE_SET_METHOD(target, "newParser", Parser::Initialize);
  NODE_SET_METHOD(target, "newSerializer", Serializer::Initialize);
}

NODE_MODULE(bindings, Initialize);
<|endoftext|>


<commit_before>/*
 *
 *                                   C R I S S C R O S S
 *                          A multi purpose cross platform library.
 *                              formerly Codename "Technetium"
 *                             project started August 14, 2006
 *
 * Copyright (c) 2006, Steven Noonan <steven@uplinklabs.net>, Rudolf Olah <omouse@gmail.com>,
 * and Miah Clayton <miah@io-in.com>. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright notice, this list
 *       of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice, this
 *       list of conditions and the following disclaimer in the documentation and/or other
 *       materials provided with the distribution.
 *     * Neither the name of Uplink Laboratories nor the names of its contributors may be
 *       used to endorse or promote products derived from this software without specific
 *       prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "universal_include.h"
#include "core_exception.h"
#include "core_io.h"
#include "core_debug.h"

#if defined(ENABLE_DEBUGLOG)
#    include "core_debuglog.h"
CoreDebugLog *g_debuglog;
#endif

#include "datastructures/rbtree.h"
#include "datastructures/llist.h"

#include <exception>

using namespace std;

CoreConsole *g_stderr;
CoreConsole *g_stdout;

#ifdef DETECT_MEMORY_LEAKS

#    pragma warning ( disable: 4312 )

#    ifdef ENABLE_MEMLEAK_STATS
_CrtMemState s1, s2, s3;
#    endif

void
ParseMemoryLeakFile ( const char *_inputFilename,
                      const char *_outputFilename )
{

    //
    // Start up
    //

    RedBlackTree < int, char *>combined;
    RedBlackTree < int, char *>frequency;
    int unrecognised = 0;

    //
    // Open the file and start parsing
    //

    std::ifstream memoryfile ( _inputFilename );

    while ( !memoryfile.eof () )
    {
        char thisline[256];

        memoryfile.getline ( thisline, 256 );

        if ( !strncmp ( thisline, " Data:", 6 ) == 0 &&    // This line is a data line - useless to us
             strchr ( thisline, ':' ) )
        {                        // This line does not have a source file location - useless to us

            // Get the size

            char *lastcomma = strrchr ( thisline, ',' );
            char *ssize = lastcomma + 2;
            int size;
            char unused[32];

            sscanf ( ssize, "%d %s", &size, unused );

            // Get the source file name

            char *sourcelocation = thisline;
            char *colon = strrchr ( thisline, ':' );

            *( colon - 1 ) = '\x0';

            // Put the result into our BTree

            RedBlackTree < int, char *>::nodeType * btree =
                combined.findNode ( sourcelocation );
            if ( btree )
                ( ( int ) btree->data ) += size;
            else
                combined.PutData ( sourcelocation, size );

            RedBlackTree < int, char *>::nodeType * freq =
                frequency.findNode ( sourcelocation );
            if ( freq )
                ( ( int ) freq->data )++;
            else
                frequency.PutData ( sourcelocation, 1 );

        }
        else
        {
            char *lastcomma = strrchr ( thisline, ',' );

            if ( lastcomma )
            {

                char *ssize = lastcomma + 2;
                int size;
                char unused[32];

                sscanf ( ssize, "%d %s", &size, unused );

                unrecognised += size;
            }
        }
    }

    memoryfile.close ();

    //
    // Sort the results into a list
    //

    DArray < int >*sizes = combined.ConvertToDArray ();
    DArray < char *>*sources = combined.ConvertIndexToDArray ();
    LList < char *>sorted;
    int totalsize = 0;

    for ( int i = 0; i < sources->Size (); ++i )
    {
        char *newsource = sources->GetData ( i );
        int newsize = sizes->GetData ( i );

        totalsize += newsize;
        bool inserted = false;

        for ( int j = 0; j < sorted.Size (); ++j )
        {

            char *existingsource = sorted.GetData ( j );
            int existingsize = combined.GetData ( existingsource );

            if ( newsize <= existingsize )
            {

                sorted.PutDataAtIndex ( newsource, j );
                inserted = true;
                break;

            }

        }

        if ( !inserted )
            sorted.PutDataAtEnd ( newsource );
    }

    //
    // Open the output file
    //

    if ( sorted.Size() )
    {
        FILE *output = fopen ( _outputFilename, "wt" );

        //
        // Print out our sorted list
        //

        fprintf ( output, "Total recognised memory leaks   : %d Kbytes\n",
                int ( totalsize / 1024 ) );
        fprintf ( output, "Total unrecognised memory leaks : %d Kbytes\n\n",
                int ( unrecognised / 1024 ) );

        for ( int k = sorted.Size () - 1; k >= 0; --k )
        {

            char *source = sorted.GetData ( k );
            int size = combined.GetData ( source );
            int freq = frequency.GetData ( source );

            if ( size > 2048 )
            {
                fprintf ( output, "%-95s (%d Kbytes in %d leaks)\n", source,
                        int ( size / 1024 ), freq );
            }
            else
            {
                fprintf ( output, "%-95s (%d  bytes in %d leaks)\n", source, size,
                        freq );
            }
        }

        //
        // Clear up

        fclose ( output );
    }

    delete sources;
    delete sizes;
}

void
AppPrintMemoryLeaks ( char *_filename )
{
    //
    // Print all raw memory leak data to a temporary file

#    ifdef ENABLE_MEMLEAK_STATS
    _CrtMemCheckpoint ( &s2 );
#    endif

    char tmpFilename[512];

    sprintf ( tmpFilename, "%s.tmp", _filename );

    OFSTRUCT ofstruct;
    HFILE file = OpenFile ( tmpFilename,
                            &ofstruct,
                            OF_CREATE );

    _CrtSetReportMode ( _CRT_WARN, _CRTDBG_MODE_FILE );
    _CrtSetReportFile ( _CRT_WARN, ( _HFILE ) file );

    _CrtDumpMemoryLeaks ();
#    ifdef ENABLE_MEMLEAK_STATS
    _CrtMemDifference ( &s3, &s1, &s2 );
    _CrtMemDumpStatistics ( &s3 );
#    endif

    _lclose ( file );

    //
    // Parse the temp file into a sensible format

    ParseMemoryLeakFile ( tmpFilename, _filename );

    //
    // Delete the temporary file

#    ifdef TARGET_OS_WINDOWS
    DeleteFile ( tmpFilename );
#    else
    unlink ( tmpFilename );
#    endif

}
#endif

#if 0
int APIENTRY
WinMain ( HINSTANCE hInstance,
          HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
#else
int
main ( int argc, char **argv )
{
#endif
    /* TODO: Get proper command line parameters for Windows apps */
    int retval = 0;

#ifdef ENABLE_MEMLEAK_STATS
    _CrtMemCheckpoint ( &s1 );
#endif
    g_stderr = new CoreConsole ( stderr );
    g_stdout = new CoreConsole ( stdout );
#ifdef ENABLE_DEBUGLOG
    g_debuglog = new CoreDebugLog ( APP_NAME, APP_VERSION, APP_URL, "bugs@uplinklabs.net", false );
    g_debuglog->Write ( g_debuglog->BUG_LEVEL_INFO, "Initializing" );
#endif

#ifdef ENABLE_CREDITS
    g_stdout->
        WriteLine
        ( "Powered by " APP_NAME ", " APP_URL );
    g_stdout->WriteLine ( APP_COPYRIGHT_CONSOLE );
    g_stdout->WriteLine ();
#endif
    try
    {
#if 0
        retval = RunApplication ( 0, NULL );
#else
        retval = RunApplication ( argc, argv );
#endif
    }
    catch ( std::exception& e )
    {
        cout << e.what() << endl;
        return -3;
    }
    catch ( CoreException * e )
    {
        g_stderr->
            WriteLine
            ( "\nA CoreException has been raised.\n\tFile: %s\n\tLine: %d\n\tDescription: %s\n",
              e->ShowFile (), e->ShowLine (), e->ShowReason () );
        return -1;
    }
    catch ( const char *_exception )
    {
        g_stderr->
            WriteLine
            ( "An unknown exception has been raised:\n\tDescription: %s",
              _exception );
        return -2;
    }

#ifdef ENABLE_DEBUGLOG

    g_debuglog->Write ( g_debuglog->BUG_LEVEL_INFO, "Exiting", "" );

    // Below commented only because I hate cleaning out .log files. Uncomment if you wish. -- Steven
    // g_debuglog->Save();

    delete g_debuglog;

#endif

    delete g_stderr;
    delete g_stdout;

#ifdef DETECT_MEMORY_LEAKS
    AppPrintMemoryLeaks ( "memleak.txt" );
#endif
    return retval;
}
<commit_msg>Added some colour. Yay for spice.<commit_after>/*
 *
 *                                   C R I S S C R O S S
 *                          A multi purpose cross platform library.
 *                              formerly Codename "Technetium"
 *                             project started August 14, 2006
 *
 * Copyright (c) 2006, Steven Noonan <steven@uplinklabs.net>, Rudolf Olah <omouse@gmail.com>,
 * and Miah Clayton <miah@io-in.com>. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright notice, this list
 *       of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice, this
 *       list of conditions and the following disclaimer in the documentation and/or other
 *       materials provided with the distribution.
 *     * Neither the name of Uplink Laboratories nor the names of its contributors may be
 *       used to endorse or promote products derived from this software without specific
 *       prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "universal_include.h"
#include "core_exception.h"
#include "core_io.h"
#include "core_debug.h"

#if defined(ENABLE_DEBUGLOG)
#    include "core_debuglog.h"
CoreDebugLog *g_debuglog;
#endif

#include "datastructures/rbtree.h"
#include "datastructures/llist.h"

#include <exception>

using namespace std;

CoreConsole *g_stderr;
CoreConsole *g_stdout;

#ifdef DETECT_MEMORY_LEAKS

#    pragma warning ( disable: 4312 )

#    ifdef ENABLE_MEMLEAK_STATS
_CrtMemState s1, s2, s3;
#    endif

void
ParseMemoryLeakFile ( const char *_inputFilename,
                      const char *_outputFilename )
{

    //
    // Start up
    //

    RedBlackTree < int, char *>combined;
    RedBlackTree < int, char *>frequency;
    int unrecognised = 0;

    //
    // Open the file and start parsing
    //

    std::ifstream memoryfile ( _inputFilename );

    while ( !memoryfile.eof () )
    {
        char thisline[256];

        memoryfile.getline ( thisline, 256 );

        if ( !strncmp ( thisline, " Data:", 6 ) == 0 &&    // This line is a data line - useless to us
             strchr ( thisline, ':' ) )
        {                        // This line does not have a source file location - useless to us

            // Get the size

            char *lastcomma = strrchr ( thisline, ',' );
            char *ssize = lastcomma + 2;
            int size;
            char unused[32];

            sscanf ( ssize, "%d %s", &size, unused );

            // Get the source file name

            char *sourcelocation = thisline;
            char *colon = strrchr ( thisline, ':' );

            *( colon - 1 ) = '\x0';

            // Put the result into our BTree

            RedBlackTree < int, char *>::nodeType * btree =
                combined.findNode ( sourcelocation );
            if ( btree )
                ( ( int ) btree->data ) += size;
            else
                combined.PutData ( sourcelocation, size );

            RedBlackTree < int, char *>::nodeType * freq =
                frequency.findNode ( sourcelocation );
            if ( freq )
                ( ( int ) freq->data )++;
            else
                frequency.PutData ( sourcelocation, 1 );

        }
        else
        {
            char *lastcomma = strrchr ( thisline, ',' );

            if ( lastcomma )
            {

                char *ssize = lastcomma + 2;
                int size;
                char unused[32];

                sscanf ( ssize, "%d %s", &size, unused );

                unrecognised += size;
            }
        }
    }

    memoryfile.close ();

    //
    // Sort the results into a list
    //

    DArray < int >*sizes = combined.ConvertToDArray ();
    DArray < char *>*sources = combined.ConvertIndexToDArray ();
    LList < char *>sorted;
    int totalsize = 0;

    for ( int i = 0; i < sources->Size (); ++i )
    {
        char *newsource = sources->GetData ( i );
        int newsize = sizes->GetData ( i );

        totalsize += newsize;
        bool inserted = false;

        for ( int j = 0; j < sorted.Size (); ++j )
        {

            char *existingsource = sorted.GetData ( j );
            int existingsize = combined.GetData ( existingsource );

            if ( newsize <= existingsize )
            {

                sorted.PutDataAtIndex ( newsource, j );
                inserted = true;
                break;

            }

        }

        if ( !inserted )
            sorted.PutDataAtEnd ( newsource );
    }

    //
    // Open the output file
    //

    if ( sorted.Size() )
    {
        FILE *output = fopen ( _outputFilename, "wt" );

        //
        // Print out our sorted list
        //

        fprintf ( output, "Total recognised memory leaks   : %d Kbytes\n",
                int ( totalsize / 1024 ) );
        fprintf ( output, "Total unrecognised memory leaks : %d Kbytes\n\n",
                int ( unrecognised / 1024 ) );

        for ( int k = sorted.Size () - 1; k >= 0; --k )
        {

            char *source = sorted.GetData ( k );
            int size = combined.GetData ( source );
            int freq = frequency.GetData ( source );

            if ( size > 2048 )
            {
                fprintf ( output, "%-95s (%d Kbytes in %d leaks)\n", source,
                        int ( size / 1024 ), freq );
            }
            else
            {
                fprintf ( output, "%-95s (%d  bytes in %d leaks)\n", source, size,
                        freq );
            }
        }

        //
        // Clear up

        fclose ( output );
    }

    delete sources;
    delete sizes;
}

void
AppPrintMemoryLeaks ( char *_filename )
{
    //
    // Print all raw memory leak data to a temporary file

#    ifdef ENABLE_MEMLEAK_STATS
    _CrtMemCheckpoint ( &s2 );
#    endif

    char tmpFilename[512];

    sprintf ( tmpFilename, "%s.tmp", _filename );

    OFSTRUCT ofstruct;
    HFILE file = OpenFile ( tmpFilename,
                            &ofstruct,
                            OF_CREATE );

    _CrtSetReportMode ( _CRT_WARN, _CRTDBG_MODE_FILE );
    _CrtSetReportFile ( _CRT_WARN, ( _HFILE ) file );

    _CrtDumpMemoryLeaks ();
#    ifdef ENABLE_MEMLEAK_STATS
    _CrtMemDifference ( &s3, &s1, &s2 );
    _CrtMemDumpStatistics ( &s3 );
#    endif

    _lclose ( file );

    //
    // Parse the temp file into a sensible format

    ParseMemoryLeakFile ( tmpFilename, _filename );

    //
    // Delete the temporary file

#    ifdef TARGET_OS_WINDOWS
    DeleteFile ( tmpFilename );
#    else
    unlink ( tmpFilename );
#    endif

}
#endif

#if 0
int APIENTRY
WinMain ( HINSTANCE hInstance,
          HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
#else
int
main ( int argc, char **argv )
{
#endif
    /* TODO: Get proper command line parameters for Windows apps */
    int retval = 0;

#ifdef ENABLE_MEMLEAK_STATS
    _CrtMemCheckpoint ( &s1 );
#endif
    g_stderr = new CoreConsole ( stderr );
    g_stdout = new CoreConsole ( stdout );
#ifdef ENABLE_DEBUGLOG
    g_debuglog = new CoreDebugLog ( APP_NAME, APP_VERSION, APP_URL, "bugs@uplinklabs.net", false );
    g_debuglog->Write ( g_debuglog->BUG_LEVEL_INFO, "Initializing" );
#endif

#ifdef ENABLE_CREDITS
    g_stdout->SetColour ( g_stdout->FG_GREEN | g_stdout->FG_INTENSITY );
    g_stdout->WriteLine ( "Powered by " APP_NAME ", " APP_URL );
    g_stdout->SetColour ( 0 );
    g_stdout->WriteLine ( APP_COPYRIGHT_CONSOLE );
    g_stdout->WriteLine ();
#endif
    try
    {
#if 0
        retval = RunApplication ( 0, NULL );
#else
        retval = RunApplication ( argc, argv );
#endif
    }
    catch ( std::exception& e )
    {
        cout << e.what() << endl;
        return -3;
    }
    catch ( CoreException * e )
    {
        g_stderr->
            WriteLine
            ( "\nA CoreException has been raised.\n\tFile: %s\n\tLine: %d\n\tDescription: %s\n",
              e->ShowFile (), e->ShowLine (), e->ShowReason () );
        return -1;
    }
    catch ( const char *_exception )
    {
        g_stderr->
            WriteLine
            ( "An unknown exception has been raised:\n\tDescription: %s",
              _exception );
        return -2;
    }

#ifdef ENABLE_DEBUGLOG

    g_debuglog->Write ( g_debuglog->BUG_LEVEL_INFO, "Exiting", "" );

    // Below commented only because I hate cleaning out .log files. Uncomment if you wish. -- Steven
    // g_debuglog->Save();

    delete g_debuglog;

#endif

    delete g_stderr;
    delete g_stdout;

#ifdef DETECT_MEMORY_LEAKS
    AppPrintMemoryLeaks ( "memleak.txt" );
#endif
    return retval;
}
<|endoftext|>


<commit_before>#include "navigate.h"

#include <assert.h>
#include <cstdio>
#include <string.h>
#include <cmath>

#define  REAL_TYPE_SIZE  (sizeof(real))

union charDouble
{
    char c[ REAL_TYPE_SIZE ];
    real db;
};

/**
 * @brief toDouble
 * 转换double型数据的字节序
 *
 * @param x
 */
void toDouble(real &x)
{
    charDouble cd;
    cd.db = x;

    char c[REAL_TYPE_SIZE] = {0};
    int  tpsize = REAL_TYPE_SIZE;

    for ( int i = 0; i < tpsize; ++i)
        c[i] = cd.c[tpsize-i-1];
    x = *(real*)c;
}
/**
 * @brief toBigEndian
 * 转换int型数据字节序
 * @param x
 */
void  toBigEndian(int& x)
{
    x = ( (x & 0x000000ff) << 24 ) | ( (x & 0x0000ff00) << 8)
            | ((x & 0x00ff0000) >> 8) | ( (x & 0xff000000) >> 24);
}

Navigate::Navigate()
{
    _coordsys = LeftHandSys;
}

Navigate::~Navigate()
{
    vector<Node*>::iterator ptiter= __points.begin();

    while ( ptiter != __points.end() )
    {
        delete *ptiter;
        ptiter = __points.erase(ptiter);
    }

    ClearResult();
}

list<Node*> Navigate::GetNeighbor(Node *center)
{
    vector<int> ids = center->neigbours;
    list<Node*> res;
    for ( size_t i = 0 ; i < ids.size(); i++ )
    {
        if (_id2points[ids[i]]->type != 1)
            res.push_back(_id2points[ids[i]]);
    }
    return res;

}

void Navigate::LoadPointsFile(const char *file)
{

    //二进制文件读取
    FILE *f = fopen(file,"rb");
    char buf[32] = {0};
    int floorcount = 0;

    if ( NULL == f )
        return;

    //楼层编号
    fread(buf,1,32,f);
    //楼层数
    fread(&floorcount,sizeof(int),1,f);
    toBigEndian(floorcount);
    if ( floorcount <= 0) return;

    //for 楼层
    for ( int k = 0 ; k < floorcount; ++k)
    {
        int count = 0, floor = 0;
        //楼层编号
        fread(buf,1,32,f);
        fread(&floor,sizeof(int),1,f);
        toBigEndian(floor);
        //总点数
        fread(&count,sizeof(int),1,f);
        toBigEndian(count);
        list<int>  lnd;
        _floor_binds[count] = lnd;
        //for 楼层点
        for ( int i = 0 ; i < count; ++i)
        {
            Node *nd = new Node;

            //楼层
            nd->floor = floor;
            fread(&nd->id,sizeof(int),1,f);
            toBigEndian(nd->id);

            //点类型
            fread(&nd->type,sizeof(int),1,f);
            toBigEndian(nd->type);
            fread(&nd->x,sizeof(real),1,f);
            toDouble(nd->x);

            fread(&nd->y,sizeof(real),1,f);
            toDouble(nd->y);
            //相邻路口数
            int nbcount;
            fread(&nbcount,sizeof(int),1,f);
            toBigEndian(nbcount);
            nd->neigbours.resize(nbcount);
            for ( int j = 0 ; j < nbcount; ++j)
            {
                fread(&nd->neigbours[j],sizeof(int),1,f);
                toBigEndian(nd->neigbours[j]);
            }
            _id2points[nd->id] = nd;
            __points.push_back(nd);

            if ( nd->type == Bind )
            {
                _binds.push_back(nd);
                lnd.push_back(nd->id);
                _floor_binds[nd->floor] = lnd;
            }
        }//end for 楼层点
    }//end for 楼层
    fclose(f);
}

list<Node*> Navigate::GetBestPath(Node *start, Node *end)
{
    ClearResult();
    bool    bfinded = true;
    list<Node*> result;
    //起点终点相同，不予导航
    if ( EQUAL(start->x , end->x) && EQUAL(start->y,end->y))
        return result;
    //未给定路径，不予导航
    if (__points.size() <= 0)
        return result;

    assert(start != NULL && end != NULL);

    start = GetNearPathNode(start);
    end = GetNearPathNode(end);

    _start = start;
    _end = end;

    list<Node*> neighbor = GetNeighbor(start);
    list<Node*>::iterator iter = neighbor.begin();

    for ( ; iter != neighbor.end(); ++iter)
    {
        AddToOpenList( start,*iter );
    }
    AddToCloseList( start );

    Node *nstart = start;
    //memcpy(&nstart,start,sizeof(Node));
    while ( !IsInPath(_closeList,end) )
    {
        if ( _openList.empty())
        {
            bfinded = false;
            break;
        }
        //从开放集中获取最小F值的数据点并加入封闭集中
        Node *min_nd = GetMiniFNode(nstart);
//        cout<<"Min Node:"<<min_nd->x<<" ,"<<min_nd->y<<end;
        nstart = min_nd;
        AddToCloseList(min_nd);
        RemoveFromOpenList(min_nd);

        //检查并更新该点邻域数值
        list<Node*> newneighbor = GetNeighbor(min_nd);
        list<Node*> ::iterator nbiter = newneighbor.begin();
        for ( ; nbiter != newneighbor.end(); ++nbiter )
        {
            // 分两种情况
            if ( IsInPath(_closeList,*nbiter))
                continue;
            //1: 未在开放集中,更新父节点及g值，放入开放集中
            if ( !IsInPath(_openList,*nbiter))
            {
                (*nbiter)->parent = min_nd;
                (*nbiter)->g = min_nd->g + GetGValue(min_nd,*nbiter);
                AddToOpenList(min_nd,*nbiter);
            }
            //2: 已在开放集中,发掘更优路径
            else
            {
                real g = min_nd->g + GetGValue(min_nd,*nbiter);
                if ( g < (*nbiter)->g )
                {
                    (*nbiter)->parent = min_nd;
                    (*nbiter)->g = g;
                }
            }
        }
    }

    if ( !bfinded ){

        cout<<"Can not Find"<<endl;
        return result;

    }
    else{
        cout<<"Finded and Path node cout:"<<_closeList.size()<<endl;
    }
    Node *nd = _closeList.front();
    result.push_front(end);
    while ( (*nd)!=(*start) )
    {
        result.push_front(nd->parent);
        nd = nd->parent;
    }
    //result.push_front(start);
    _closeList.clear();
    _openList.clear();
    UpdateDirect(result);
    return result;
}

//为尽可能简化程序，提高运行效率
//该方法认为要添加的点在开放集中不存在，直接添加
void Navigate::AddToOpenList(Node *parent,Node *center)
{
    Node *nd = new Node;

    memcpy(nd,center,sizeof(Node));
    nd->parent = parent;
    _openList.push_front(nd);
}

void Navigate::AddToCloseList(Node *center)
{
    Node *nd = new Node;

    memcpy(nd,center,sizeof(Node));
    nd->parent = center->parent;
    _closeList.push_front(nd);
}

void Navigate::ClearResult()
{
    list<Node*> ::iterator it1 = _openList.begin();
    while ( it1 != _openList.end())
    {
        delete *it1;
        it1 = _openList.erase(it1);
    }

    list<Node*> ::iterator it2 = _closeList.begin();
    while ( it2!= _closeList.end() )
    {
        delete *it2;
        it2 = _openList.erase(it2);
    }
}

real Navigate::GetGValue(Node *n1, Node *n2)
{
    real dx = n1->x - n2->x;
    real dy = n2->y - n1->y;

    return sqrt( dx * dx + dy * dy );
}
bool Navigate::IsInPath(list<Node *> path, Node *nd)
{
    if ( path.size() <= 0 || nd == NULL )
        return false;
    list<Node*>::iterator it = path.begin();
    for ( ; it != path.end() ; ++it )
    {
        if ( EQUAL( (*it)->x,nd->x) && EQUAL( (*it)->y,nd->y) )
            return true;
    }
    return false;
}
void Navigate::RemoveFromCloseList(Node *nd)
{
    list<Node*>::iterator iter = _closeList.begin();
    while ( iter != _closeList.end())
    {
        if ( EQUAL((*iter)->x,nd->x) && EQUAL((*iter)->y,nd->y) )
        {
            iter = _closeList.erase(iter);
        }else
            ++iter;
    }
}
void Navigate::RemoveFromOpenList(Node *nd)
{
    list<Node*>::iterator iter = _openList.begin();
    while ( iter != _openList.end())
    {
        if ( EQUAL((*iter)->x,nd->x) && EQUAL((*iter)->y,nd->y) )
        {
            iter = _openList.erase(iter);
        }else
            ++iter;
    }
}
Node* Navigate::GetMiniFNode(Node *cur)
{
    list<Node*>::iterator iter = _openList.begin();
    real minf = INVALID;
    bool flag = false;
    Node *res;

    for ( ; iter != _openList.end(); ++iter )
    {
        real g = cur->g + GetGValue(cur,*iter);
        (*iter)->h = GetGValue(*iter,_end);
        real f = g + (*iter)->h;
        if ( f < minf )
        {
            flag = true;
            minf = f;
            res = (*iter);
        }
    }

    return res;
}

//
//根据路径更新路径点的方向信息
//路径中至少需包含三个数据点
void Navigate::UpdateDirect(list<Node *> &path)
{
    if ( path.size() < 3)
        return;

    list<Node*>::iterator iter = path.begin();
    Node *nd1 = *iter;
    Node *nd2 = NULL;
    Node *nd3 = NULL;

    nd2 = *(++iter);
    nd3 = *(++iter);
    --iter;
    --iter;

    nd1->attr = WalkDirect;
    for( iter ; iter != path.end(); ++iter )
    {

        Vec v12(nd2->x - nd1->x, nd2->y - nd1->y),
            v13(nd3->x - nd1->x, nd3->y - nd1->y);

        real cross = VectorCrossMulti(&v12,&v13);
        if ( cross < 0)
        {
            nd2->attr = TurnRight;
        }else if ( cross > 0 )
        {
            nd2->attr = TurnLeft;
        }else
            nd2->attr = WalkDirect;

        if ( nd2->neighborcount <= 2)
            nd2->attr = WalkAlong;

        nd1 = nd2;
        nd2 = nd3;
        ++iter; //2
        ++iter; //3
        ++iter; //下一个要处理的点
        if ( iter == path.end())
        {
            (*(--iter))->attr = Arrive;
            break;
        }
        nd3 = *(iter);
        --iter;
        --iter;
        --iter;
    }

}

Node *Navigate::GetNearPathNode(Node *nd)
{
    real mindis = INVALID;
    Node *res = NULL;
    int i = 0, count = __points.size();
    for ( i = 0 ; i < count; ++i)
    {
        real dis = Distance(nd,__points[i]);
        if ( dis < mindis)
        {
            mindis = dis;
            res = __points[i];
        }
    }
    return res;
}

Node *Navigate::getNearestBind(Node *ndsrc)
{
    real    mindis = INVALID;
    int     floor = ndsrc->floor;
    Node    *res = NULL;

    if ( _floor_binds.find(floor) == _floor_binds.end() )
        return NULL;
    list<int>   lbs = _floor_binds[floor];

    list<int>::iterator it = lbs.begin();
    while ( it != lbs.end() )
    {
        Node *nd = GetPoint(*it);
        real dis = Distance(ndsrc,nd);
        if ( dis <= mindis)
        {
            mindis = dis;
            res = nd;
        }
        ++it;
    }

    return res;
}
<commit_msg>modify neighborhood information<commit_after>#include "navigate.h"

#include <assert.h>
#include <cstdio>
#include <string.h>
#include <cmath>

#define  REAL_TYPE_SIZE  (sizeof(real))

union charDouble
{
    char c[ REAL_TYPE_SIZE ];
    real db;
};

/**
 * @brief toDouble
 * 转换double型数据的字节序
 *
 * @param x
 */
void toDouble(real &x)
{
    charDouble cd;
    cd.db = x;

    char c[REAL_TYPE_SIZE] = {0};
    int  tpsize = REAL_TYPE_SIZE;

    for ( int i = 0; i < tpsize; ++i)
        c[i] = cd.c[tpsize-i-1];
    x = *(real*)c;
}
/**
 * @brief toBigEndian
 * 转换int型数据字节序
 * @param x
 */
void  toBigEndian(int& x)
{
    x = ( (x & 0x000000ff) << 24 ) | ( (x & 0x0000ff00) << 8)
            | ((x & 0x00ff0000) >> 8) | ( (x & 0xff000000) >> 24);
}

Navigate::Navigate()
{
    _coordsys = LeftHandSys;
}

Navigate::~Navigate()
{
    vector<Node*>::iterator ptiter= __points.begin();

    while ( ptiter != __points.end() )
    {
        delete *ptiter;
        ptiter = __points.erase(ptiter);
    }

    ClearResult();
}

list<Node*> Navigate::GetNeighbor(Node *center)
{
    vector<int> ids = center->neigbours;
    list<Node*> res;
    for ( size_t i = 0 ; i < ids.size(); i++ )
    {
        if (_id2points[ids[i]]->type != 1)
            res.push_back(_id2points[ids[i]]);
    }
    return res;

}

void Navigate::LoadPointsFile(const char *file)
{

    //二进制文件读取
    FILE *f = fopen(file,"rb");
    char buf[32] = {0};
    int floorcount = 0,k = 0;

    if ( NULL == f )
        return;

    //楼层编号
    fread(buf,1,32,f);
    //楼层数
    fread(&floorcount,sizeof(int),1,f);
    toBigEndian(floorcount);
    if ( floorcount <= 0) return;

    //for 楼层
    for ( k = 0 ; k < floorcount;k++)
    {
        int count = 0, floor = 0;
        //楼层编号
        fread(buf,1,32,f);
        fread(&floor,sizeof(int),1,f);
        toBigEndian(floor);
        //总点数
        fread(&count,sizeof(int),1,f);
        toBigEndian(count);
        list<int>  lnd;
        _floor_binds[count] = lnd;
        //for 楼层点
        for ( int i = 0 ; i < count; ++i)
        {
            Node *nd = new Node;

            //楼层
            nd->floor = floor;
            fread(&nd->id,sizeof(int),1,f);
            toBigEndian(nd->id);

            //点类型
            fread(&nd->type,sizeof(int),1,f);
            toBigEndian(nd->type);
            fread(&nd->x,sizeof(real),1,f);
            toDouble(nd->x);

            fread(&nd->y,sizeof(real),1,f);
            toDouble(nd->y);
            //相邻路口数
            int nbcount;
            fread(&nbcount,sizeof(int),1,f);
            toBigEndian(nbcount);
            nd->neighborcount = nbcount;
            nd->neigbours.resize(nbcount);
            for ( int j = 0 ; j < nbcount; ++j)
            {
                fread(&nd->neigbours[j],sizeof(int),1,f);
                toBigEndian(nd->neigbours[j]);
            }
            _id2points[nd->id] = nd;
            __points.push_back(nd);

            if ( nd->type == Bind )
            {
                _binds.push_back(nd);
                lnd.push_back(nd->id);
                _floor_binds[nd->floor] = lnd;
            }
        }//end for 楼层点
    }//end for 楼层
    fclose(f);
}

list<Node*> Navigate::GetBestPath(Node *start, Node *end)
{
    ClearResult();
    bool    bfinded = true;
    list<Node*> result;
    //起点终点相同，不予导航
    if ( EQUAL(start->x , end->x) && EQUAL(start->y,end->y))
        return result;
    //未给定路径，不予导航
    if (__points.size() <= 0)
        return result;

    assert(start != NULL && end != NULL);

    start = GetNearPathNode(start);
    end = GetNearPathNode(end);

    _start = start;
    _end = end;

    list<Node*> neighbor = GetNeighbor(start);
    list<Node*>::iterator iter = neighbor.begin();

    for ( ; iter != neighbor.end(); ++iter)
    {
        AddToOpenList( start,*iter );
    }
    AddToCloseList( start );

    Node *nstart = start;
    //memcpy(&nstart,start,sizeof(Node));
    while ( !IsInPath(_closeList,end) )
    {
        if ( _openList.empty())
        {
            bfinded = false;
            break;
        }
        //从开放集中获取最小F值的数据点并加入封闭集中
        Node *min_nd = GetMiniFNode(nstart);
//        cout<<"Min Node:"<<min_nd->x<<" ,"<<min_nd->y<<end;
        nstart = min_nd;
        AddToCloseList(min_nd);
        RemoveFromOpenList(min_nd);

        //检查并更新该点邻域数值
        list<Node*> newneighbor = GetNeighbor(min_nd);
        list<Node*> ::iterator nbiter = newneighbor.begin();
        for ( ; nbiter != newneighbor.end(); ++nbiter )
        {
            // 分两种情况
            if ( IsInPath(_closeList,*nbiter))
                continue;
            //1: 未在开放集中,更新父节点及g值，放入开放集中
            if ( !IsInPath(_openList,*nbiter))
            {
                (*nbiter)->parent = min_nd;
                (*nbiter)->g = min_nd->g + GetGValue(min_nd,*nbiter);
                AddToOpenList(min_nd,*nbiter);
            }
            //2: 已在开放集中,发掘更优路径
            else
            {
                real g = min_nd->g + GetGValue(min_nd,*nbiter);
                if ( g < (*nbiter)->g )
                {
                    (*nbiter)->parent = min_nd;
                    (*nbiter)->g = g;
                }
            }
        }
    }

    if ( !bfinded ){

        cout<<"Can not Find"<<endl;
        return result;

    }
    else{
        cout<<"Finded and Path node cout:"<<_closeList.size()<<endl;
    }
    Node *nd = _closeList.front();
    result.push_front(end);
    while ( (*nd)!=(*start) )
    {
        result.push_front(nd->parent);
        nd = nd->parent;
    }
    //result.push_front(start);
    _closeList.clear();
    _openList.clear();
    UpdateDirect(result);
    return result;
}

//为尽可能简化程序，提高运行效率
//该方法认为要添加的点在开放集中不存在，直接添加
void Navigate::AddToOpenList(Node *parent,Node *center)
{
    Node *nd = new Node;

    memcpy(nd,center,sizeof(Node));
    nd->parent = parent;
    _openList.push_front(nd);
}

void Navigate::AddToCloseList(Node *center)
{
    Node *nd = new Node;

    memcpy(nd,center,sizeof(Node));
    nd->parent = center->parent;
    _closeList.push_front(nd);
}

void Navigate::ClearResult()
{
    list<Node*> ::iterator it1 = _openList.begin();
    while ( it1 != _openList.end())
    {
        delete *it1;
        it1 = _openList.erase(it1);
    }

    list<Node*> ::iterator it2 = _closeList.begin();
    while ( it2!= _closeList.end() )
    {
        delete *it2;
        it2 = _openList.erase(it2);
    }
}

real Navigate::GetGValue(Node *n1, Node *n2)
{
    real dx = n1->x - n2->x;
    real dy = n2->y - n1->y;

    return sqrt( dx * dx + dy * dy );
}
bool Navigate::IsInPath(list<Node *> path, Node *nd)
{
    if ( path.size() <= 0 || nd == NULL )
        return false;
    list<Node*>::iterator it = path.begin();
    for ( ; it != path.end() ; ++it )
    {
        if ( EQUAL( (*it)->x,nd->x) && EQUAL( (*it)->y,nd->y) )
            return true;
    }
    return false;
}
void Navigate::RemoveFromCloseList(Node *nd)
{
    list<Node*>::iterator iter = _closeList.begin();
    while ( iter != _closeList.end())
    {
        if ( EQUAL((*iter)->x,nd->x) && EQUAL((*iter)->y,nd->y) )
        {
            iter = _closeList.erase(iter);
        }else
            ++iter;
    }
}
void Navigate::RemoveFromOpenList(Node *nd)
{
    list<Node*>::iterator iter = _openList.begin();
    while ( iter != _openList.end())
    {
        if ( EQUAL((*iter)->x,nd->x) && EQUAL((*iter)->y,nd->y) )
        {
            iter = _openList.erase(iter);
        }else
            ++iter;
    }
}
Node* Navigate::GetMiniFNode(Node *cur)
{
    list<Node*>::iterator iter = _openList.begin();
    real minf = INVALID;
    bool flag = false;
    Node *res;

    for ( ; iter != _openList.end(); ++iter )
    {
        real g = cur->g + GetGValue(cur,*iter);
        (*iter)->h = GetGValue(*iter,_end);
        real f = g + (*iter)->h;
        if ( f < minf )
        {
            flag = true;
            minf = f;
            res = (*iter);
        }
    }

    return res;
}

//
//根据路径更新路径点的方向信息
//路径中至少需包含三个数据点
void Navigate::UpdateDirect(list<Node *> &path)
{
    if ( path.size() < 3)
        return;

    list<Node*>::iterator iter = path.begin();
    Node *nd1 = *iter;
    Node *nd2 = NULL;
    Node *nd3 = NULL;

    nd2 = *(++iter);
    nd3 = *(++iter);
    --iter;
    --iter;

    nd1->attr = WalkDirect;
    for( iter ; iter != path.end(); ++iter )
    {

        Vec v12(nd2->x - nd1->x, nd2->y - nd1->y),
            v13(nd3->x - nd1->x, nd3->y - nd1->y);

        real cross = VectorCrossMulti(&v12,&v13);
        if ( cross < 0)
        {
            nd2->attr = TurnRight;
        }else if ( cross > 0 )
        {
            nd2->attr = TurnLeft;
        }else
        {
            nd2->attr = WalkDirect;
        }

        if ( nd2->neighborcount <= 2)
        {
            nd2->attr = WalkAlong;
        }

        nd1 = nd2;
        nd2 = nd3;
        ++iter; //2
        ++iter; //3
        ++iter; //下一个要处理的点
        if ( iter == path.end())
        {
            (*(--iter))->attr = Arrive;
            break;
        }
        nd3 = *(iter);
        --iter;
        --iter;
        --iter;
    }

}

Node *Navigate::GetNearPathNode(Node *nd)
{
    real mindis = INVALID;
    Node *res = NULL;
    int i = 0, count = __points.size();
    for ( i = 0 ; i < count; ++i)
    {
        real dis = Distance(nd,__points[i]);
        if ( dis < mindis)
        {
            mindis = dis;
            res = __points[i];
        }
    }
    return res;
}

Node *Navigate::getNearestBind(Node *ndsrc)
{
    real    mindis = INVALID;
    int     floor = ndsrc->floor;
    Node    *res = NULL;

    if ( _floor_binds.find(floor) == _floor_binds.end() )
        return NULL;
    list<int>   lbs = _floor_binds[floor];

    list<int>::iterator it = lbs.begin();
    while ( it != lbs.end() )
    {
        Node *nd = GetPoint(*it);
        real dis = Distance(ndsrc,nd);
        if ( dis <= mindis)
        {
            mindis = dis;
            res = nd;
        }
        ++it;
    }

    return res;
}
<|endoftext|>


<commit_before>#include "process.hpp"
#include <cstring>
#include <TlHelp32.h>
#include <stdexcept>

Process::Data::Data(): id(0), handle(NULL) {}

//Based on the discussion thread: https://www.reddit.com/r/cpp/comments/3vpjqg/a_new_platform_independent_process_library_for_c11/cxq1wsj
std::mutex create_process_mutex;

//Based on the example at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx.
Process::id_type Process::open(const std::string &command, const std::string &path) {
  if(open_stdin)
    stdin_fd=std::unique_ptr<fd_type>(new fd_type(NULL));
  if(read_stdout)
    stdout_fd=std::unique_ptr<fd_type>(new fd_type(NULL));
  if(read_stderr)
    stderr_fd=std::unique_ptr<fd_type>(new fd_type(NULL));

  HANDLE stdin_rd_p = NULL;
  HANDLE stdin_wr_p = NULL;
  HANDLE stdout_rd_p = NULL;
  HANDLE stdout_wr_p = NULL;
  HANDLE stderr_rd_p = NULL;
  HANDLE stderr_wr_p = NULL;

  SECURITY_ATTRIBUTES security_attributes;

  security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  security_attributes.bInheritHandle = TRUE;
  security_attributes.lpSecurityDescriptor = NULL;

  std::lock_guard<std::mutex> lock(create_process_mutex);
  if(stdin_fd) {
    if (!CreatePipe(&stdin_rd_p, &stdin_wr_p, &security_attributes, 0)) {
      return 0;
    }
    if(!SetHandleInformation(stdin_wr_p, HANDLE_FLAG_INHERIT, 0)) {
      CloseHandle(stdin_rd_p);CloseHandle(stdin_wr_p);
      return 0;
    }
  }
  if(stdout_fd) {
    if (!CreatePipe(&stdout_rd_p, &stdout_wr_p, &security_attributes, 0)) {
      if(stdin_fd) {CloseHandle(stdin_rd_p);CloseHandle(stdin_wr_p);}
      return 0;
    }
    if(!SetHandleInformation(stdout_rd_p, HANDLE_FLAG_INHERIT, 0)) {
      if(stdin_fd) {CloseHandle(stdin_rd_p);CloseHandle(stdin_wr_p);}
      CloseHandle(stdout_rd_p);CloseHandle(stdout_wr_p);
      return 0;
    }
  }
  if(stderr_fd) {
    if (!CreatePipe(&stderr_rd_p, &stderr_wr_p, &security_attributes, 0)) {
      if(stdin_fd) {CloseHandle(stdin_rd_p);CloseHandle(stdin_wr_p);}
      if(stdout_fd) {CloseHandle(stdout_rd_p);CloseHandle(stdout_wr_p);}
      return 0;
    }
    if(!SetHandleInformation(stderr_rd_p, HANDLE_FLAG_INHERIT, 0)) {
      if(stdin_fd) {CloseHandle(stdin_rd_p);CloseHandle(stdin_wr_p);}
      if(stdout_fd) {CloseHandle(stdout_rd_p);CloseHandle(stdout_wr_p);}
      CloseHandle(stderr_rd_p);CloseHandle(stderr_wr_p);
      return 0;
    }
  }

  PROCESS_INFORMATION process_info;
  STARTUPINFO startup_info;

  ZeroMemory(&process_info, sizeof(PROCESS_INFORMATION));

  ZeroMemory(&startup_info, sizeof(STARTUPINFO));
  startup_info.cb = sizeof(STARTUPINFO);
  startup_info.hStdInput = stdin_fd?stdin_rd_p:INVALID_HANDLE_VALUE;
  startup_info.hStdOutput = stdout_fd?stdout_wr_p:INVALID_HANDLE_VALUE;
  startup_info.hStdError = stderr_fd?stderr_wr_p:INVALID_HANDLE_VALUE;
  if(stdin_fd || stdout_fd || stderr_fd)
    startup_info.dwFlags |= STARTF_USESTDHANDLES;

  char* path_cstr;
  if(path=="")
    path_cstr=NULL;
  else {
    path_cstr=new char[path.size()+1];
    std::strcpy(path_cstr, path.c_str());
  }

  char* command_cstr;
#ifdef MSYS_PROCESS_USE_SH
  size_t pos=0;
  std::string sh_command=command;
  while((pos=sh_command.find('\\', pos))!=std::string::npos) {
    sh_command.replace(pos, 1, "\\\\\\\\");
    pos+=4;
  }
  pos=0;
  while((pos=sh_command.find('\"', pos))!=std::string::npos) {
    sh_command.replace(pos, 1, "\\\"");
    pos+=2;
  }
  sh_command.insert(0, "sh -c \"");
  sh_command+="\"";
  command_cstr=new char[sh_command.size()+1];
  std::strcpy(command_cstr, sh_command.c_str());
#else
  command_cstr=new char[command.size()+1];
  std::strcpy(command_cstr, command.c_str());
#endif

  BOOL bSuccess = CreateProcess(NULL, command_cstr, NULL, NULL, TRUE, 0,
                                NULL, path_cstr, &startup_info, &process_info);
  delete[] path_cstr;
  delete[] command_cstr;

  if(!bSuccess) {
    CloseHandle(process_info.hProcess);
    CloseHandle(process_info.hThread);
    if(stdin_fd) {CloseHandle(stdin_rd_p);CloseHandle(stdin_wr_p);}
    if(stdout_fd) {CloseHandle(stdout_rd_p);CloseHandle(stdout_wr_p);}
    if(stderr_fd) {CloseHandle(stderr_rd_p);CloseHandle(stderr_wr_p);}
    return 0;
  }
  else {
    CloseHandle(process_info.hThread);
    if(stdin_fd) CloseHandle(stdin_rd_p);
    if(stdout_fd) CloseHandle(stdout_wr_p);
    if(stderr_fd) CloseHandle(stderr_wr_p);
  }

  if(stdin_fd) *stdin_fd=stdin_wr_p;
  if(stdout_fd) *stdout_fd=stdout_rd_p;
  if(stderr_fd) *stderr_fd=stderr_rd_p;

  closed=false;
  data.id=process_info.dwProcessId;
  data.handle=process_info.hProcess;
  return process_info.dwProcessId;
}

void Process::async_read() {
  if(data.id==0)
    return;
  if(stdout_fd) {
    stdout_thread=std::thread([this](){
      DWORD n;
      std::unique_ptr<char[]> buffer(new char[buffer_size]);
      for (;;) {
        BOOL bSuccess = ReadFile(*stdout_fd, static_cast<CHAR*>(buffer.get()), static_cast<DWORD>(buffer_size), &n, NULL);
        if(!bSuccess || n == 0)
          break;
        read_stdout(buffer.get(), static_cast<size_t>(n));
      }
    });
  }
  if(stderr_fd) {
    stderr_thread=std::thread([this](){
      DWORD n;
      std::unique_ptr<char[]> buffer(new char[buffer_size]);
      for (;;) {
        BOOL bSuccess = ReadFile(*stderr_fd, static_cast<CHAR*>(buffer.get()), static_cast<DWORD>(buffer_size), &n, NULL);
        if(!bSuccess || n == 0)
          break;
        read_stderr(buffer.get(), static_cast<size_t>(n));
      }
    });
  }
}

int Process::get_exit_status() {
  if(data.id==0)
    return -1;
  DWORD exit_status;
  WaitForSingleObject(data.handle, INFINITE);
  if(!GetExitCodeProcess(data.handle, &exit_status))
    exit_status=-1;
  {
    std::lock_guard<std::mutex> lock(close_mutex);
    CloseHandle(data.handle);
    closed=true;
  }
  close_fds();

  return static_cast<int>(exit_status);
}

void Process::close_fds() {
  if(stdout_thread.joinable())
    stdout_thread.join();
  if(stderr_thread.joinable())
    stderr_thread.join();

  if(stdin_fd)
    close_stdin();
  if(stdout_fd && *stdout_fd != NULL) {
    CloseHandle(*stdout_fd);
    stdout_fd.reset();
  }
  if(stderr_fd && *stderr_fd != NULL) {
    CloseHandle(*stderr_fd);
    stderr_fd.reset();
  }
}

bool Process::write(const char *bytes, size_t n) {
  if(!open_stdin)
    throw std::invalid_argument("Can't write to an unopened stdin pipe. Please set open_stdin=true when constructing the process.");

  std::lock_guard<std::mutex> lock(stdin_mutex);
  if(stdin_fd) {
    DWORD written;
    BOOL bSuccess=WriteFile(*stdin_fd, bytes, static_cast<DWORD>(n), &written, NULL);
    if(!bSuccess || written==0) {
      return false;
    }
    else {
      return true;
    }
  }
  return false;
}

void Process::close_stdin() {
  std::lock_guard<std::mutex> lock(stdin_mutex);
  if(stdin_fd && *stdin_fd != NULL) {
    CloseHandle(*stdin_fd);
    stdin_fd.reset();
  }
}

//Based on http://stackoverflow.com/a/1173396
void Process::kill(bool force) {
  std::lock_guard<std::mutex> lock(close_mutex);
  if(data.id>0 && !closed) {
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if(snapshot) {
      PROCESSENTRY32 process;
      ZeroMemory(&process, sizeof(process));
      process.dwSize = sizeof(process);
      if(Process32First(snapshot, &process)) {
        do {
          if(process.th32ParentProcessID==data.id) {
            HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
            if(process_handle) TerminateProcess(process_handle, 2);
          }
        } while (Process32Next(snapshot, &process));
      }
    }
    TerminateProcess(data.handle, 2);
  }
}

//Based on http://stackoverflow.com/a/1173396
void Process::kill(id_type id, bool force) {
  if(id==0)
    return;
  HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if(snapshot) {
    PROCESSENTRY32 process;
    ZeroMemory(&process, sizeof(process));
    process.dwSize = sizeof(process);
    if(Process32First(snapshot, &process)) {
      do {
        if(process.th32ParentProcessID==id) {
          HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
          if(process_handle) TerminateProcess(process_handle, 2);
        }
      } while (Process32Next(snapshot, &process));
    }
  }
  HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
  if(process_handle) TerminateProcess(process_handle, 2);
}
<commit_msg>On Windows, double check to avoid calling CloseHandle on not initialized handle, when CreateProcess fails. Update to always reset unique_ptr.<commit_after>#include "process.hpp"
#include <cstring>
#include <TlHelp32.h>
#include <stdexcept>

Process::Data::Data(): id(0), handle(NULL) {}

//Based on the discussion thread: https://www.reddit.com/r/cpp/comments/3vpjqg/a_new_platform_independent_process_library_for_c11/cxq1wsj
std::mutex create_process_mutex;

//Based on the example at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx.
Process::id_type Process::open(const std::string &command, const std::string &path) {
  if(open_stdin)
    stdin_fd=std::unique_ptr<fd_type>(new fd_type(NULL));
  if(read_stdout)
    stdout_fd=std::unique_ptr<fd_type>(new fd_type(NULL));
  if(read_stderr)
    stderr_fd=std::unique_ptr<fd_type>(new fd_type(NULL));

  HANDLE stdin_rd_p = NULL;
  HANDLE stdin_wr_p = NULL;
  HANDLE stdout_rd_p = NULL;
  HANDLE stdout_wr_p = NULL;
  HANDLE stderr_rd_p = NULL;
  HANDLE stderr_wr_p = NULL;

  SECURITY_ATTRIBUTES security_attributes;

  security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  security_attributes.bInheritHandle = TRUE;
  security_attributes.lpSecurityDescriptor = NULL;

  std::lock_guard<std::mutex> lock(create_process_mutex);
  if(stdin_fd) {
    if (!CreatePipe(&stdin_rd_p, &stdin_wr_p, &security_attributes, 0)) {
      return 0;
    }
    if(!SetHandleInformation(stdin_wr_p, HANDLE_FLAG_INHERIT, 0)) {
      CloseHandle(stdin_rd_p);CloseHandle(stdin_wr_p);
      return 0;
    }
  }
  if(stdout_fd) {
    if (!CreatePipe(&stdout_rd_p, &stdout_wr_p, &security_attributes, 0)) {
      if(stdin_fd) {CloseHandle(stdin_rd_p);CloseHandle(stdin_wr_p);}
      return 0;
    }
    if(!SetHandleInformation(stdout_rd_p, HANDLE_FLAG_INHERIT, 0)) {
      if(stdin_fd) {CloseHandle(stdin_rd_p);CloseHandle(stdin_wr_p);}
      CloseHandle(stdout_rd_p);CloseHandle(stdout_wr_p);
      return 0;
    }
  }
  if(stderr_fd) {
    if (!CreatePipe(&stderr_rd_p, &stderr_wr_p, &security_attributes, 0)) {
      if(stdin_fd) {CloseHandle(stdin_rd_p);CloseHandle(stdin_wr_p);}
      if(stdout_fd) {CloseHandle(stdout_rd_p);CloseHandle(stdout_wr_p);}
      return 0;
    }
    if(!SetHandleInformation(stderr_rd_p, HANDLE_FLAG_INHERIT, 0)) {
      if(stdin_fd) {CloseHandle(stdin_rd_p);CloseHandle(stdin_wr_p);}
      if(stdout_fd) {CloseHandle(stdout_rd_p);CloseHandle(stdout_wr_p);}
      CloseHandle(stderr_rd_p);CloseHandle(stderr_wr_p);
      return 0;
    }
  }

  PROCESS_INFORMATION process_info;
  STARTUPINFO startup_info;

  ZeroMemory(&process_info, sizeof(PROCESS_INFORMATION));

  ZeroMemory(&startup_info, sizeof(STARTUPINFO));
  startup_info.cb = sizeof(STARTUPINFO);
  startup_info.hStdInput = stdin_fd?stdin_rd_p:INVALID_HANDLE_VALUE;
  startup_info.hStdOutput = stdout_fd?stdout_wr_p:INVALID_HANDLE_VALUE;
  startup_info.hStdError = stderr_fd?stderr_wr_p:INVALID_HANDLE_VALUE;
  if(stdin_fd || stdout_fd || stderr_fd)
    startup_info.dwFlags |= STARTF_USESTDHANDLES;

  char* path_cstr;
  if(path=="")
    path_cstr=NULL;
  else {
    path_cstr=new char[path.size()+1];
    std::strcpy(path_cstr, path.c_str());
  }

  char* command_cstr;
#ifdef MSYS_PROCESS_USE_SH
  size_t pos=0;
  std::string sh_command=command;
  while((pos=sh_command.find('\\', pos))!=std::string::npos) {
    sh_command.replace(pos, 1, "\\\\\\\\");
    pos+=4;
  }
  pos=0;
  while((pos=sh_command.find('\"', pos))!=std::string::npos) {
    sh_command.replace(pos, 1, "\\\"");
    pos+=2;
  }
  sh_command.insert(0, "sh -c \"");
  sh_command+="\"";
  command_cstr=new char[sh_command.size()+1];
  std::strcpy(command_cstr, sh_command.c_str());
#else
  command_cstr=new char[command.size()+1];
  std::strcpy(command_cstr, command.c_str());
#endif

  BOOL bSuccess = CreateProcess(NULL, command_cstr, NULL, NULL, TRUE, 0,
                                NULL, path_cstr, &startup_info, &process_info);
  delete[] path_cstr;
  delete[] command_cstr;

  if(!bSuccess) {
    CloseHandle(process_info.hProcess);
    CloseHandle(process_info.hThread);
    if(stdin_fd) {CloseHandle(stdin_rd_p);CloseHandle(stdin_wr_p);}
    if(stdout_fd) {CloseHandle(stdout_rd_p);CloseHandle(stdout_wr_p);}
    if(stderr_fd) {CloseHandle(stderr_rd_p);CloseHandle(stderr_wr_p);}
    return 0;
  }
  else {
    CloseHandle(process_info.hThread);
    if(stdin_fd) CloseHandle(stdin_rd_p);
    if(stdout_fd) CloseHandle(stdout_wr_p);
    if(stderr_fd) CloseHandle(stderr_wr_p);
  }

  if(stdin_fd) *stdin_fd=stdin_wr_p;
  if(stdout_fd) *stdout_fd=stdout_rd_p;
  if(stderr_fd) *stderr_fd=stderr_rd_p;

  closed=false;
  data.id=process_info.dwProcessId;
  data.handle=process_info.hProcess;
  return process_info.dwProcessId;
}

void Process::async_read() {
  if(data.id==0)
    return;
  if(stdout_fd) {
    stdout_thread=std::thread([this](){
      DWORD n;
      std::unique_ptr<char[]> buffer(new char[buffer_size]);
      for (;;) {
        BOOL bSuccess = ReadFile(*stdout_fd, static_cast<CHAR*>(buffer.get()), static_cast<DWORD>(buffer_size), &n, NULL);
        if(!bSuccess || n == 0)
          break;
        read_stdout(buffer.get(), static_cast<size_t>(n));
      }
    });
  }
  if(stderr_fd) {
    stderr_thread=std::thread([this](){
      DWORD n;
      std::unique_ptr<char[]> buffer(new char[buffer_size]);
      for (;;) {
        BOOL bSuccess = ReadFile(*stderr_fd, static_cast<CHAR*>(buffer.get()), static_cast<DWORD>(buffer_size), &n, NULL);
        if(!bSuccess || n == 0)
          break;
        read_stderr(buffer.get(), static_cast<size_t>(n));
      }
    });
  }
}

int Process::get_exit_status() {
  if(data.id==0)
    return -1;
  DWORD exit_status;
  WaitForSingleObject(data.handle, INFINITE);
  if(!GetExitCodeProcess(data.handle, &exit_status))
    exit_status=-1;
  {
    std::lock_guard<std::mutex> lock(close_mutex);
    CloseHandle(data.handle);
    closed=true;
  }
  close_fds();

  return static_cast<int>(exit_status);
}

void Process::close_fds() {
  if(stdout_thread.joinable())
    stdout_thread.join();
  if(stderr_thread.joinable())
    stderr_thread.join();

  if(stdin_fd)
    close_stdin();
  if(stdout_fd) {
    if(*stdout_fd!=NULL) CloseHandle(*stdout_fd);
    stdout_fd.reset();
  }
  if(stderr_fd) {
    if(*stderr_fd!=NULL) CloseHandle(*stderr_fd);
    stderr_fd.reset();
  }
}

bool Process::write(const char *bytes, size_t n) {
  if(!open_stdin)
    throw std::invalid_argument("Can't write to an unopened stdin pipe. Please set open_stdin=true when constructing the process.");

  std::lock_guard<std::mutex> lock(stdin_mutex);
  if(stdin_fd) {
    DWORD written;
    BOOL bSuccess=WriteFile(*stdin_fd, bytes, static_cast<DWORD>(n), &written, NULL);
    if(!bSuccess || written==0) {
      return false;
    }
    else {
      return true;
    }
  }
  return false;
}

void Process::close_stdin() {
  std::lock_guard<std::mutex> lock(stdin_mutex);
  if(stdin_fd) {
    if(*stdin_fd!=NULL) CloseHandle(*stdin_fd);
    stdin_fd.reset();
  }
}

//Based on http://stackoverflow.com/a/1173396
void Process::kill(bool force) {
  std::lock_guard<std::mutex> lock(close_mutex);
  if(data.id>0 && !closed) {
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if(snapshot) {
      PROCESSENTRY32 process;
      ZeroMemory(&process, sizeof(process));
      process.dwSize = sizeof(process);
      if(Process32First(snapshot, &process)) {
        do {
          if(process.th32ParentProcessID==data.id) {
            HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
            if(process_handle) TerminateProcess(process_handle, 2);
          }
        } while (Process32Next(snapshot, &process));
      }
    }
    TerminateProcess(data.handle, 2);
  }
}

//Based on http://stackoverflow.com/a/1173396
void Process::kill(id_type id, bool force) {
  if(id==0)
    return;
  HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if(snapshot) {
    PROCESSENTRY32 process;
    ZeroMemory(&process, sizeof(process));
    process.dwSize = sizeof(process);
    if(Process32First(snapshot, &process)) {
      do {
        if(process.th32ParentProcessID==id) {
          HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
          if(process_handle) TerminateProcess(process_handle, 2);
        }
      } while (Process32Next(snapshot, &process));
    }
  }
  HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
  if(process_handle) TerminateProcess(process_handle, 2);
}
<|endoftext|>


<commit_before>
<commit_msg>Delete a.cpp<commit_after><|endoftext|>