<commit_before>// RefCount.hh for FbTk - Fluxbox Toolkit
// Copyright (c) 2002 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

#ifndef FBTK_REFCOUNT_HH
#define FBTK_REFCOUNT_HH

namespace FbTk {

/// holds a pointer with reference counting, similar to std:auto_ptr
template <typename Pointer>
class RefCount {
public:
    RefCount();
    explicit RefCount(Pointer *p);
    explicit RefCount(RefCount<Pointer> &copy);
    explicit RefCount(const RefCount<Pointer> &copy);
    ~RefCount();
    RefCount<Pointer> &operator = (const RefCount<Pointer> &copy);
    RefCount<Pointer> &operator = (Pointer *p);
    Pointer *operator * () const { return get(); }
    Pointer *operator -> () const { return get(); }
    Pointer *get() const { return m_data; }
    /// @return number of referenses
    unsigned int usedBy() const { return (m_refcount != 0 ? *m_refcount : 0); }
private:
    /// increase referense count
    void incRefCount();
    /// decrease referense count
    void decRefCount();
    Pointer *m_data; ///< data holder
    mutable unsigned int *m_refcount; ///< holds reference counting
};

// implementation

template <typename Pointer>
RefCount<Pointer>::RefCount():m_data(0), m_refcount(new unsigned int(0)) {

}

template <typename Pointer>
RefCount<Pointer>::RefCount(RefCount<Pointer> &copy):
    m_data(copy.m_data),
    m_refcount(copy.m_refcount) {
    incRefCount();
}

template <typename Pointer>
RefCount<Pointer>::RefCount(Pointer *p):m_data(p), m_refcount(new unsigned int(0)) {
    incRefCount();
}

template <typename Pointer>
RefCount<Pointer>::RefCount(const RefCount<Pointer> &copy):
    m_data(copy.m_data),
    m_refcount(copy.m_refcount) {
    incRefCount();
}

template <typename Pointer>
RefCount<Pointer>::~RefCount() {
    decRefCount();
}

template <typename Pointer>
RefCount<Pointer> &RefCount<Pointer>::operator = (const RefCount<Pointer> &copy) {
    decRefCount(); // dec current ref count
    m_refcount = copy.m_refcount; // set new ref count
    m_data = copy.m_data; // set new data pointer
    incRefCount(); // inc new ref count
    return *this;
}

template <typename Pointer>
RefCount<Pointer> &RefCount<Pointer>::operator = (Pointer *p) {
    decRefCount();
    m_data = p; // set data pointer
    m_refcount = new unsigned int(0); // create new counter
    incRefCount();
}

template <typename Pointer>
void RefCount<Pointer>::decRefCount() {
    if (m_refcount == 0)
        return;
    if (*m_refcount == 0) { // already zero, then delete refcount
        delete m_refcount;
        m_refcount = 0;
        return;
    }
    (*m_refcount)--;
    if (*m_refcount == 0) { // destroy m_data and m_refcount if nobody else is using this
        if (m_data != 0)
            delete m_data;
        m_data = 0;
        delete m_refcount;
        m_refcount = 0;
    }
}

template <typename Pointer>
void RefCount<Pointer>::incRefCount() {
    if (m_refcount == 0)
        return;
    (*m_refcount)++;
}

}; // end namespace FbTk

#endif // FBTK_REFCOUNT_HH
<commit_msg>removed explicit from copy constructor<commit_after>// RefCount.hh for FbTk - Fluxbox Toolkit
// Copyright (c) 2002 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

#ifndef FBTK_REFCOUNT_HH
#define FBTK_REFCOUNT_HH

namespace FbTk {

/// holds a pointer with reference counting, similar to std:auto_ptr
template <typename Pointer>
class RefCount {
public:
    RefCount();
    explicit RefCount(Pointer *p);
    explicit RefCount(RefCount<Pointer> &copy);
    RefCount(const RefCount<Pointer> &copy);
    ~RefCount();
    RefCount<Pointer> &operator = (const RefCount<Pointer> &copy);
    RefCount<Pointer> &operator = (Pointer *p);
    Pointer *operator * () const { return get(); }
    Pointer *operator -> () const { return get(); }
    Pointer *get() const { return m_data; }
    /// @return number of referenses
    unsigned int usedBy() const { return (m_refcount != 0 ? *m_refcount : 0); }
private:
    /// increase referense count
    void incRefCount();
    /// decrease referense count
    void decRefCount();
    Pointer *m_data; ///< data holder
    mutable unsigned int *m_refcount; ///< holds reference counting
};

// implementation

template <typename Pointer>
RefCount<Pointer>::RefCount():m_data(0), m_refcount(new unsigned int(0)) {

}

template <typename Pointer>
RefCount<Pointer>::RefCount(RefCount<Pointer> &copy):
    m_data(copy.m_data),
    m_refcount(copy.m_refcount) {
    incRefCount();
}

template <typename Pointer>
RefCount<Pointer>::RefCount(Pointer *p):m_data(p), m_refcount(new unsigned int(0)) {
    incRefCount();
}

template <typename Pointer>
RefCount<Pointer>::RefCount(const RefCount<Pointer> &copy):
    m_data(copy.m_data),
    m_refcount(copy.m_refcount) {
    incRefCount();
}

template <typename Pointer>
RefCount<Pointer>::~RefCount() {
    decRefCount();
}

template <typename Pointer>
RefCount<Pointer> &RefCount<Pointer>::operator = (const RefCount<Pointer> &copy) {
    decRefCount(); // dec current ref count
    m_refcount = copy.m_refcount; // set new ref count
    m_data = copy.m_data; // set new data pointer
    incRefCount(); // inc new ref count
    return *this;
}

template <typename Pointer>
RefCount<Pointer> &RefCount<Pointer>::operator = (Pointer *p) {
    decRefCount();
    m_data = p; // set data pointer
    m_refcount = new unsigned int(0); // create new counter
    incRefCount();
}

template <typename Pointer>
void RefCount<Pointer>::decRefCount() {
    if (m_refcount == 0)
        return;
    if (*m_refcount == 0) { // already zero, then delete refcount
        delete m_refcount;
        m_refcount = 0;
        return;
    }
    (*m_refcount)--;
    if (*m_refcount == 0) { // destroy m_data and m_refcount if nobody else is using this
        if (m_data != 0)
            delete m_data;
        m_data = 0;
        delete m_refcount;
        m_refcount = 0;
    }
}

template <typename Pointer>
void RefCount<Pointer>::incRefCount() {
    if (m_refcount == 0)
        return;
    (*m_refcount)++;
}

}; // end namespace FbTk

#endif // FBTK_REFCOUNT_HH
<|endoftext|>


<commit_before>/**
* \file      main.cc
* \brief     Program for giving an indication when a RFID card has been
* detected, a database connection has been made and a string has been encrypted
* \author    Tim IJntema, Stefan de Beer, Arco Gelderblom, Rik Honcoop, Koen de
* Groot, Ricardo Bouwman, Philippe Zwietering, Luuk Steeman, Leo Jenneskens,
* Jeremy Ruijzenaars
* \copyright Copyright (c) 2017, The R2D2 Team
* \license   See LICENSE
*/

#include "config-file-parser.hh"
#include "database-manager.hh"
#include "led-controller.hh"
#include "matrix-keypad.hh"
#include "mfrc522.hh"

#include <wiringPiSPI.h>

#include <iomanip>

int main(int argc, char **argv) {
#define USING_PIN // Comment out this rule if not using a pin code on your
    // application
    std::string ip;
    std::string username;
    std::string password;

    ConfigFileParser factory("database-config.txt");
    factory.loadDatabaseSettings(ip, username, password);

    MySql connection;

    std::cout << "Made connection to the database\n";
    wiringPiSetup();
    wiringPiSPISetup(0, 10000000); // max speed for mfrc522 is 10Mhz
    MFRC522 rfid;
    rfid.PCD_Init();

    // Keypad pinSetup
    const int keypadRow[] = {15, 16, 1, 4};
    const int keypadColumn[] = {8, 9, 7, 2};

    // Keypad objects
    MatrixKeypad keypad(keypadRow, keypadColumn, 4);

    LedController redLed(0);
    LedController greenLed(11);
    DatabaseManager information;
    information.connectTo(ip, username, password);
    information.selectDatabase("R2D2");
    while (true) {
        delay(1000);
        std::cout << "\n\nWaiting for RFID tag: \n";

        if (!rfid.PICC_IsNewCardPresent())
            continue;

        if (!rfid.PICC_ReadCardSerial())
            continue;

        std::string id;
        for (byte i = 0; i < rfid.uid.size; ++i) {
            std::stringstream ss;
            ss << std::hex << (int) rfid.uid.uidByte[i];
            std::string res(ss.str());
            id += res;
            if (i != rfid.uid.size - 1) {
                id += ' ';
            }
        }

        bool inDatabase;
        std::cout << id << " is the presented ID\n";
        if (!information.isCardInDatabase(id)) {
            std::cout << "This ID is in the database\n";
            inDatabase = 1;
        } else {
            std::cout << "This ID is NOT in the database\n";
            inDatabase = 0;
        }

#ifdef USING_PIN
        MFRC522::MIFARE_Key key = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
        if (1 !=
            rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
                                  (byte) 0x05, &key, &rfid.uid))
            continue;

        // read pin code
        byte bufferSize = (byte) 18;
        byte readArray[18] = {0, 0, 0, 0, 0, 0, 0, 0, 0,
                              0, 0, 0, 0, 0, 0, 0, 0, 0};
        rfid.MIFARE_Read((byte) 0x05, readArray, &bufferSize);
        std::cout << "Read array contains: \n";
        for (int i = 0; i < 18; i++) {
            std::cout << (int) readArray[i] << ' ';
        }

        // enter pin code
        std::cout << "\nInput PIN and finish with #\n";
        std::string value = keypad.getString();

        // write pin code
        byte writeArray[16] = {0, 0, 0, 0, 0, 0, 0, 0,
                               0, 0, 0, 0, 0, 0, 0, 0};
        int index = 0;
        for (auto c : value) {
            if (c > 47 && c < 58) {
                int number = c - 48;
                writeArray[index++] = (byte) number;
            }
        }
        rfid.MIFARE_Write((byte) 0x05, writeArray, (byte) 16);
        std::cout << "Write array contains: \n";
        for (int i = 0; i < 16; i++) {
            std::cout << (int) writeArray[i] << ' ';
        }

#endif
        rfid.PCD_StopCrypto1();
        if (inDatabase) {
            greenLed.blinkLed(3000);
        } else {
            redLed.blinkLed(3000);
        }
    }
}
<commit_msg>[RFID-03] Changed all the stuff according to the review on pr 31<commit_after>/**
* \file      main.cc
* \brief     Program for giving an indication when a RFID card has been
* detected, a database connection has been made and a string has been encrypted
* \author    Tim IJntema, Stefan de Beer, Arco Gelderblom, Rik Honcoop, Koen de
* Groot, Ricardo Bouwman, Philippe Zwietering, Luuk Steeman, Leo Jenneskens,
* Jeremy Ruijzenaars
* \copyright Copyright (c) 2017, The R2D2 Team
* \license   See LICENSE
*/

#include "config-file-parser.hh"
#include "database-manager.hh"
#include "led-controller.hh"
#include "matrix-keypad.hh"
#include "mfrc522.hh"

#include <wiringPiSPI.h>

#include <iomanip>
#include <string>

// Keypad pinSetup
const int keypadRow[] = {15, 16, 1, 4};
const int keypadColumn[] = {8, 9, 7, 2};

// Magic number declarations
const int redLedPin = 0;
const int greenLedPin = 11;
const int maxSpeedWiringSPI = 10000000; // max speed for mfrc522 is 10Mhz
const int keypadColumnSize = 4;
const int blockSizeWithCrc = 18;
const int blockSize = 16;
const int zeroAscii = 47;
const int nineAscii = 58;
const int blinkTime = 3000;

int main(int argc, char **argv) {

    if(argc != 2 || std::string(argv[1]) != "pin" && std::string(argv[1]) != "no-pin") {
        std::cerr << "Please only put in 'pin' or 'no-pin' as parameter, nothing else." << std::endl
                  << "Your function will then either look like './rfid pin' or './rfid no-pin'" << std::endl;
    }

    // Keypad objects
    MatrixKeypad keypad(keypadRow, keypadColumn, keypadColumnSize);

    LedController redLed(redLedPin);
    LedController greenLed(greenLedPin);

    std::string ip;
    std::string username;
    std::string password;

    ConfigFileParser factory("database-config.txt");
    factory.loadDatabaseSettings(ip, username, password);
    DatabaseManager information;
    information.connectTo(ip, username, password);
    information.selectDatabase("R2D2");

    std::cout << "Made connection to the database\n";
    wiringPiSetup();
    wiringPiSPISetup(0, maxSpeedWiringSPI);

    MFRC522 rfid;
    rfid.PCD_Init();

    while (true) {
        delay(1000);
        std::cout << "\n\nWaiting for RFID tag: \n";

        if (!rfid.PICC_IsNewCardPresent())
            continue;

        if (!rfid.PICC_ReadCardSerial())
            continue;

        std::string id;
        for (byte i = 0; i < rfid.uid.size; ++i) {
            std::stringstream ss;
            ss << std::hex << (int) rfid.uid.uidByte[i];
            id += ss.str();
            if (i != rfid.uid.size - 1) {
                id += ' ';
            }
        }

        bool inDatabase;
        std::cout << id << " is the presented ID\n";
        if (!information.isCardInDatabase(id)) {
            std::cout << "This ID is in the database\n";
            inDatabase = 1;
        } else {
            std::cout << "This ID is NOT in the database\n";
            inDatabase = 0;
        }

        if(std::string(argv[1]) == "pin") {
            MFRC522::MIFARE_Key key = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
            if (rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
                                      (byte) 0x05, &key, &rfid.uid) != 1)
                continue;

            // read pin code
            byte bufferSize = (byte) blockSizeWithCrc;
            byte readArray[blockSizeWithCrc] = {};
            rfid.MIFARE_Read((byte) 0x05, readArray, &bufferSize);
            std::cout << "Read array contains: \n";
            for (int i = 0; i < blockSizeWithCrc; i++) {
                std::cout << (int) readArray[i] << ' ';
            }

            // enter pin code
            std::cout << "\nInput PIN and finish with #\n";
            std::string value = keypad.getString();

            // write pin code
            byte writeArray[blockSize] = {};
            int index = 0;
            for (const auto c : value) {
                if (c > zeroAscii && c < nineAscii) {
                    int number = c - (zeroAscii+1);
                    writeArray[index++] = (byte) number;
                }
            }
            rfid.MIFARE_Write((byte) 0x05, writeArray, (byte) blockSize);
            std::cout << "Write array contains: \n";
            for (int i = 0; i < blockSize; i++) {
                std::cout << (int) writeArray[i] << ' ';
            }
        }

        rfid.PCD_StopCrypto1();
        if (inDatabase) {
            greenLed.blinkLed(blinkTime);
        } else {
            redLed.blinkLed(blinkTime);
        }
    }
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_io_erepairGetFailedLanesHwp.H
/// @brief FW Team HWP that accesses the fail lanes of Fabric and Memory buses.
///
//----------------------------------------------------------------------------
// *HWP HWP Owner       : Chris Steffen <cwsteffen@us.ibm.com>
// *HWP HWP Backup Owner: Gary Peterson <garyp@us.ibm.com>
// *HWP FW Owner        : Sumit Kumar <sumit_kumar@in.ibm.com>
// *HWP Team            : IO
// *HWP Level           : 2
// *HWP Consumed by     : FSP:HB
//----------------------------------------------------------------------------

#ifndef P9_IO_EREPAIRGETFAILEDLANESHWP_H_
#define P9_IO_EREPAIRGETFAILEDLANESHWP_H_

#include <fapi2.H>
#include <p9_io_erepairConsts.H>

typedef fapi2::ReturnCode (*p9_io_erepairGetFailedLanesHwp_FP_t)(
    const fapi2::Target < fapi2::TARGET_TYPE_XBUS |
    fapi2::TARGET_TYPE_OBUS |
    fapi2::TARGET_TYPE_MEMBUF_CHIP |
    fapi2::TARGET_TYPE_MCS_CHIPLET |
    fapi2::TARGET_TYPE_MCS >           &i_target,
    EREPAIR::erepairVpdType            i_vpdType,
    const uint8_t                      i_clkGroup,
    std::vector<uint8_t>&              o_txFailLanes,
    std::vector<uint8_t>&              o_rxFailLanes);

extern "C"
{

    /**
     * @brief FW Team HWP that retrieves the eRepair fail lanes.
     *        It retrieves the eRepair data from the P9 MVPD and the Centaur FRU
     *        VPD sections depending on the passed target type. It then parses the
     *        eRepair data to determine the fail lane numbers on the sub-interfaces
     *        (Tx and Rx) of the passed bus target.
     *
     * @param[in] i_tgtHandle   Reference to X-Bus or A-Bus or MCS or memBuf Target
     * @param[in] i_vpdType     Specifies which VPD (MNFG or Field) to access.
     * @param[in] i_clkGroup    Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
     * @param[o]  o_txFailLanes Reference to a vector that will hold eRepair fail
     *                          lane numbers of the Tx sub-interface.
     * @param[o]  o_rxFailLanes Reference to a vector that will hold eRepair fail
     *                          lane numbers of the Rx sub-interface.
     *
     * @return ReturnCode
     *
     */
    fapi2::ReturnCode p9_io_erepairGetFailedLanesHwp(
        const fapi2::Target < fapi2::TARGET_TYPE_XBUS |
        fapi2::TARGET_TYPE_OBUS |
        fapi2::TARGET_TYPE_MEMBUF_CHIP |
        fapi2::TARGET_TYPE_MCS_CHIPLET |
        fapi2::TARGET_TYPE_MCS >           &i_target,
        EREPAIR::erepairVpdType            i_vpdType,
        const uint8_t                      i_clkGroup,
        std::vector<uint8_t>&              o_txFailLanes,
        std::vector<uint8_t>&              o_rxFailLanes);

}// end of extern C

#endif
<commit_msg>erepair VPD access bug fixes<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_io_erepairGetFailedLanesHwp.H
/// @brief FW Team HWP that accesses the fail lanes of Fabric and Memory buses.
///
//----------------------------------------------------------------------------
// *HWP HWP Owner       : Chris Steffen <cwsteffen@us.ibm.com>
// *HWP HWP Backup Owner: Gary Peterson <garyp@us.ibm.com>
// *HWP FW Owner        : Sumit Kumar <sumit_kumar@in.ibm.com>
// *HWP Team            : IO
// *HWP Level           : 2
// *HWP Consumed by     : FSP:HB
//----------------------------------------------------------------------------

#ifndef P9_IO_EREPAIRGETFAILEDLANESHWP_H_
#define P9_IO_EREPAIRGETFAILEDLANESHWP_H_

#include <fapi2.H>
#include <p9_io_erepairConsts.H>

template<fapi2::TargetType K>
using p9_io_erepairGetFailedLanesHwp_FP_t = fapi2::ReturnCode (*)(
            const fapi2::Target < K >&           i_target,
            EREPAIR::erepairVpdType            i_vpdType,
            const uint8_t                      i_clkGroup,
            std::vector<uint8_t>&              o_txFailLanes,
            std::vector<uint8_t>&              o_rxFailLanes);

/**
 * @brief FW Team HWP that retrieves the eRepair fail lanes.
 *        It retrieves the eRepair data from the P9 MVPD and the Centaur FRU
 *        VPD sections depending on the passed target type. It then parses the
 *        eRepair data to determine the fail lane numbers on the sub-interfaces
 *        (Tx and Rx) of the passed bus target.
 *
 * @param[in] i_tgtHandle   Reference to X-Bus or A-Bus or MCS or memBuf Target
 * @param[in] i_vpdType     Specifies which VPD (MNFG or Field) to access.
 * @param[in] i_clkGroup    Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
 * @param[o]  o_txFailLanes Reference to a vector that will hold eRepair fail
 *                          lane numbers of the Tx sub-interface.
 * @param[o]  o_rxFailLanes Reference to a vector that will hold eRepair fail
 *                          lane numbers of the Rx sub-interface.
 *
 * @return ReturnCode
 *
 */
template<fapi2::TargetType K>
fapi2::ReturnCode p9_io_erepairGetFailedLanesHwp(
    const fapi2::Target < K >&           i_target,
    EREPAIR::erepairVpdType            i_vpdType,
    const uint8_t                      i_clkGroup,
    std::vector<uint8_t>&              o_txFailLanes,
    std::vector<uint8_t>&              o_rxFailLanes);

#endif
<|endoftext|>


<commit_before>// @(#)root/cont:$Id$
// Author: Fons Rademakers   10/08/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// THashList                                                            //
//                                                                      //
// THashList implements a hybrid collection class consisting of a       //
// hash table and a list to store TObject's. The hash table is used for //
// quick access and lookup of objects while the list allows the objects //
// to be ordered. The hash value is calculated using the value returned //
// by the TObject's Hash() function. Each class inheriting from TObject //
// can override Hash() as it sees fit.                                  //
//Begin_Html
/*
<img src=gif/thashlist.gif>
*/
//End_Html
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "THashList.h"
#include "THashTable.h"

ClassImp(THashList)

////////////////////////////////////////////////////////////////////////////////
/// Create a THashList object. Capacity is the initial hashtable capacity
/// (i.e. number of slots), by default kInitHashTableCapacity = 17, and
/// rehash is the value at which a rehash will be triggered. I.e. when the
/// average size of the linked lists at a slot becomes longer than rehash
/// then the hashtable will be resized and refilled to reduce the collision
/// rate to about 1. The higher the collision rate, i.e. the longer the
/// linked lists, the longer lookup will take. If rehash=0 the table will
/// NOT automatically be rehashed. Use Rehash() for manual rehashing.
/// WARNING !!!
/// If the name of an object in the HashList is modified, The hashlist
/// must be Rehashed

THashList::THashList(Int_t capacity, Int_t rehash)
{
   fTable = new THashTable(capacity, rehash);
}

////////////////////////////////////////////////////////////////////////////////
/// For backward compatibility only. Use other ctor.

THashList::THashList(TObject *, Int_t capacity, Int_t rehash)
{
   fTable = new THashTable(capacity, rehash);
}

////////////////////////////////////////////////////////////////////////////////
/// Delete a hashlist. Objects are not deleted unless the THashList is the
/// owner (set via SetOwner()).

THashList::~THashList()
{
   Clear();
   SafeDelete(fTable);
}

////////////////////////////////////////////////////////////////////////////////
/// Add object at the beginning of the list.

void THashList::AddFirst(TObject *obj)
{
   TList::AddFirst(obj);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Add object at the beginning of the list and also store option.
/// Storing an option is useful when one wants to change the behaviour
/// of an object a little without having to create a complete new
/// copy of the object. This feature is used, for example, by the Draw()
/// method. It allows the same object to be drawn in different ways.

void THashList::AddFirst(TObject *obj, Option_t *opt)
{
   TList::AddFirst(obj, opt);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Add object at the end of the list.

void THashList::AddLast(TObject *obj)
{
   TList::AddLast(obj);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Add object at the end of the list and also store option.
/// Storing an option is useful when one wants to change the behaviour
/// of an object a little without having to create a complete new
/// copy of the object. This feature is used, for example, by the Draw()
/// method. It allows the same object to be drawn in different ways.

void THashList::AddLast(TObject *obj, Option_t *opt)
{
   TList::AddLast(obj, opt);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Insert object before object before in the list.

void THashList::AddBefore(const TObject *before, TObject *obj)
{
   TList::AddBefore(before, obj);
   fTable->AddBefore(before, obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Insert object before object before in the list.

void THashList::AddBefore(TObjLink *before, TObject *obj)
{
   TList::AddBefore(before, obj);
   fTable->AddBefore(before->GetObject(), obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Insert object after object after in the list.

void THashList::AddAfter(const TObject *after, TObject *obj)
{
   TList::AddAfter(after, obj);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Insert object after object after in the list.

void THashList::AddAfter(TObjLink *after, TObject *obj)
{
   TList::AddAfter(after, obj);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Insert object at location idx in the list.

void THashList::AddAt(TObject *obj, Int_t idx)
{
   TList::AddAt(obj, idx);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Return the average collision rate. The higher the number the longer
/// the linked lists in the hashtable, the slower the lookup. If the number
/// is high, or lookup noticeably too slow, perfrom a Rehash().

Float_t THashList::AverageCollisions() const
{
   return fTable->AverageCollisions();
}

////////////////////////////////////////////////////////////////////////////////
/// Remove all objects from the list. Does not delete the objects unless
/// the THashList is the owner (set via SetOwner()).

void THashList::Clear(Option_t *option)
{
   fTable->Clear("nodelete");  // clear table so not more lookups
   if (IsOwner())
      TList::Delete(option);
   else
      TList::Clear(option);
}

////////////////////////////////////////////////////////////////////////////////
/// Remove all objects from the list AND delete all heap based objects.
/// If option="slow" then keep list consistent during delete. This allows
/// recursive list operations during the delete (e.g. during the dtor
/// of an object in this list one can still access the list to search for
/// other not yet deleted objects).

void THashList::Delete(Option_t *option)
{
   Bool_t slow = option ? (!strcmp(option, "slow") ? kTRUE : kFALSE) : kFALSE;

   if (!slow) {
      fTable->Clear("nodelete");     // clear table so no more lookups
      TList::Delete(option);         // this deletes the objects
   } else {
      while (fFirst) {
         TObjLink *tlk = fFirst;
         fFirst = fFirst->Next();
         fSize--;
         // remove object from table
         fTable->Remove(tlk->GetObject());
         // delete only heap objects
         if (tlk->GetObject() && tlk->GetObject()->IsOnHeap())
            TCollection::GarbageCollect(tlk->GetObject());

         delete tlk;
      }
      fFirst = fLast = fCache = 0;
      fSize  = 0;
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Find object using its name. Uses the hash value returned by the
/// TString::Hash() after converting name to a TString.

TObject *THashList::FindObject(const char *name) const
{
   return fTable->FindObject(name);
}

////////////////////////////////////////////////////////////////////////////////
/// Find object using its hash value (returned by its Hash() member).

TObject *THashList::FindObject(const TObject *obj) const
{
   return fTable->FindObject(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Return the THashTable's list (bucket) in which obj can be found based on
/// its hash; see THashTable::GetListForObject().

const TList *THashList::GetListForObject(const char *name) const
{
   return fTable->GetListForObject(name);
}

////////////////////////////////////////////////////////////////////////////////
/// Return the THashTable's list (bucket) in which obj can be found based on
/// its hash; see THashTable::GetListForObject().

const TList *THashList::GetListForObject(const TObject *obj) const
{
   return fTable->GetListForObject(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Remove object from this collection and recursively remove the object
/// from all other objects (and collections).
/// This function overrides TCollection::RecursiveRemove that calls
/// the Remove function. THashList::Remove cannot be called because
/// it uses the hash value of the hash table. This hash value
/// is not available anymore when RecursiveRemove is called from
/// the TObject destructor.

void THashList::RecursiveRemove(TObject *obj)
{
   if (!obj) return;

   // Remove obj in the list itself
   TObject *object = TList::Remove(obj);
   if (object) fTable->RemoveSlow(object);

   // Scan again the list and invoke RecursiveRemove for all objects
   TIter next(this);

   while ((object = next())) {
      if (object->TestBit(kNotDeleted)) object->RecursiveRemove(obj);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Rehash the hashlist. If the collision rate becomes too high (i.e.
/// the average size of the linked lists become too long) then lookup
/// efficiency decreases since relatively long lists have to be searched
/// every time. To improve performance rehash the hashtable. This resizes
/// the table to newCapacity slots and refills the table. Use
/// AverageCollisions() to check if you need to rehash.

void THashList::Rehash(Int_t newCapacity)
{
   fTable->Rehash(newCapacity);
}

////////////////////////////////////////////////////////////////////////////////
/// Remove object from the list.

TObject *THashList::Remove(TObject *obj)
{
   if (!obj || !fTable->FindObject(obj)) return 0;

   TList::Remove(obj);
   return fTable->Remove(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Remove object via its objlink from the list.

TObject *THashList::Remove(TObjLink *lnk)
{
   if (!lnk) return 0;

   TObject *obj = lnk->GetObject();

   TList::Remove(lnk);
   return fTable->Remove(obj);
}
<commit_msg>Doxygen & spell check<commit_after>// @(#)root/cont:$Id$
// Author: Fons Rademakers   10/08/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/** \class THashList
THashList implements a hybrid collection class consisting of a
hash table and a list to store TObject's. The hash table is used for
quick access and lookup of objects while the list allows the objects
to be ordered. The hash value is calculated using the value returned
by the TObject's Hash() function. Each class inheriting from TObject
can override Hash() as it sees fit.
*/

#include "THashList.h"
#include "THashTable.h"

ClassImp(THashList)

////////////////////////////////////////////////////////////////////////////////
/// Create a THashList object. Capacity is the initial hashtable capacity
/// (i.e. number of slots), by default kInitHashTableCapacity = 17, and
/// rehash is the value at which a rehash will be triggered. I.e. when the
/// average size of the linked lists at a slot becomes longer than rehash
/// then the hashtable will be resized and refilled to reduce the collision
/// rate to about 1. The higher the collision rate, i.e. the longer the
/// linked lists, the longer lookup will take. If rehash=0 the table will
/// NOT automatically be rehashed. Use Rehash() for manual rehashing.
///
/// WARNING !!!
/// If the name of an object in the HashList is modified, The hashlist
/// must be Rehashed

THashList::THashList(Int_t capacity, Int_t rehash)
{
   fTable = new THashTable(capacity, rehash);
}

////////////////////////////////////////////////////////////////////////////////
/// For backward compatibility only. Use other ctor.

THashList::THashList(TObject *, Int_t capacity, Int_t rehash)
{
   fTable = new THashTable(capacity, rehash);
}

////////////////////////////////////////////////////////////////////////////////
/// Delete a hashlist. Objects are not deleted unless the THashList is the
/// owner (set via SetOwner()).

THashList::~THashList()
{
   Clear();
   SafeDelete(fTable);
}

////////////////////////////////////////////////////////////////////////////////
/// Add object at the beginning of the list.

void THashList::AddFirst(TObject *obj)
{
   TList::AddFirst(obj);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Add object at the beginning of the list and also store option.
/// Storing an option is useful when one wants to change the behaviour
/// of an object a little without having to create a complete new
/// copy of the object. This feature is used, for example, by the Draw()
/// method. It allows the same object to be drawn in different ways.

void THashList::AddFirst(TObject *obj, Option_t *opt)
{
   TList::AddFirst(obj, opt);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Add object at the end of the list.

void THashList::AddLast(TObject *obj)
{
   TList::AddLast(obj);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Add object at the end of the list and also store option.
/// Storing an option is useful when one wants to change the behaviour
/// of an object a little without having to create a complete new
/// copy of the object. This feature is used, for example, by the Draw()
/// method. It allows the same object to be drawn in different ways.

void THashList::AddLast(TObject *obj, Option_t *opt)
{
   TList::AddLast(obj, opt);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Insert object before object before in the list.

void THashList::AddBefore(const TObject *before, TObject *obj)
{
   TList::AddBefore(before, obj);
   fTable->AddBefore(before, obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Insert object before object before in the list.

void THashList::AddBefore(TObjLink *before, TObject *obj)
{
   TList::AddBefore(before, obj);
   fTable->AddBefore(before->GetObject(), obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Insert object after object after in the list.

void THashList::AddAfter(const TObject *after, TObject *obj)
{
   TList::AddAfter(after, obj);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Insert object after object after in the list.

void THashList::AddAfter(TObjLink *after, TObject *obj)
{
   TList::AddAfter(after, obj);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Insert object at location idx in the list.

void THashList::AddAt(TObject *obj, Int_t idx)
{
   TList::AddAt(obj, idx);
   fTable->Add(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Return the average collision rate. The higher the number the longer
/// the linked lists in the hashtable, the slower the lookup. If the number
/// is high, or lookup noticeably too slow, perform a Rehash().

Float_t THashList::AverageCollisions() const
{
   return fTable->AverageCollisions();
}

////////////////////////////////////////////////////////////////////////////////
/// Remove all objects from the list. Does not delete the objects unless
/// the THashList is the owner (set via SetOwner()).

void THashList::Clear(Option_t *option)
{
   fTable->Clear("nodelete");  // clear table so not more lookups
   if (IsOwner())
      TList::Delete(option);
   else
      TList::Clear(option);
}

////////////////////////////////////////////////////////////////////////////////
/// Remove all objects from the list AND delete all heap based objects.
/// If option="slow" then keep list consistent during delete. This allows
/// recursive list operations during the delete (e.g. during the dtor
/// of an object in this list one can still access the list to search for
/// other not yet deleted objects).

void THashList::Delete(Option_t *option)
{
   Bool_t slow = option ? (!strcmp(option, "slow") ? kTRUE : kFALSE) : kFALSE;

   if (!slow) {
      fTable->Clear("nodelete");     // clear table so no more lookups
      TList::Delete(option);         // this deletes the objects
   } else {
      while (fFirst) {
         TObjLink *tlk = fFirst;
         fFirst = fFirst->Next();
         fSize--;
         // remove object from table
         fTable->Remove(tlk->GetObject());
         // delete only heap objects
         if (tlk->GetObject() && tlk->GetObject()->IsOnHeap())
            TCollection::GarbageCollect(tlk->GetObject());

         delete tlk;
      }
      fFirst = fLast = fCache = 0;
      fSize  = 0;
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Find object using its name. Uses the hash value returned by the
/// TString::Hash() after converting name to a TString.

TObject *THashList::FindObject(const char *name) const
{
   return fTable->FindObject(name);
}

////////////////////////////////////////////////////////////////////////////////
/// Find object using its hash value (returned by its Hash() member).

TObject *THashList::FindObject(const TObject *obj) const
{
   return fTable->FindObject(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Return the THashTable's list (bucket) in which obj can be found based on
/// its hash; see THashTable::GetListForObject().

const TList *THashList::GetListForObject(const char *name) const
{
   return fTable->GetListForObject(name);
}

////////////////////////////////////////////////////////////////////////////////
/// Return the THashTable's list (bucket) in which obj can be found based on
/// its hash; see THashTable::GetListForObject().

const TList *THashList::GetListForObject(const TObject *obj) const
{
   return fTable->GetListForObject(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Remove object from this collection and recursively remove the object
/// from all other objects (and collections).
/// This function overrides TCollection::RecursiveRemove that calls
/// the Remove function. THashList::Remove cannot be called because
/// it uses the hash value of the hash table. This hash value
/// is not available anymore when RecursiveRemove is called from
/// the TObject destructor.

void THashList::RecursiveRemove(TObject *obj)
{
   if (!obj) return;

   // Remove obj in the list itself
   TObject *object = TList::Remove(obj);
   if (object) fTable->RemoveSlow(object);

   // Scan again the list and invoke RecursiveRemove for all objects
   TIter next(this);

   while ((object = next())) {
      if (object->TestBit(kNotDeleted)) object->RecursiveRemove(obj);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Rehash the hashlist. If the collision rate becomes too high (i.e.
/// the average size of the linked lists become too long) then lookup
/// efficiency decreases since relatively long lists have to be searched
/// every time. To improve performance rehash the hashtable. This resizes
/// the table to newCapacity slots and refills the table. Use
/// AverageCollisions() to check if you need to rehash.

void THashList::Rehash(Int_t newCapacity)
{
   fTable->Rehash(newCapacity);
}

////////////////////////////////////////////////////////////////////////////////
/// Remove object from the list.

TObject *THashList::Remove(TObject *obj)
{
   if (!obj || !fTable->FindObject(obj)) return 0;

   TList::Remove(obj);
   return fTable->Remove(obj);
}

////////////////////////////////////////////////////////////////////////////////
/// Remove object via its objlink from the list.

TObject *THashList::Remove(TObjLink *lnk)
{
   if (!lnk) return 0;

   TObject *obj = lnk->GetObject();

   TList::Remove(lnk);
   return fTable->Remove(obj);
}
<|endoftext|>


<commit_before>/**
  * @file matriz_bit3.cpp
  * @brief Implementación de funciones para MatrizBit de tipo 3
  *
  */

const int MAX_POS = 16;

bool Inicializar (MatrizBit& m, int fils, int cols)
{
  bool exito = fils * cols <= m.MAX_ESPACIO && fils >= 0 && cols >= 0;

  if (exito)
  {
    m.espacio = (fils << MAX_POS) | cols;

    for (int i = 0; i < fils * cols; i++)
      m.v[i] = '0';
  }

  return exito;
}

//________________________________________________________________

int GetFilas (const MatrizBit& m)
{
  return m.espacio >> MAX_POS;
}

//________________________________________________________________

int GetColumnas (const MatrizBit& m)
{
  return m.espacio & 0xFFFF;
}
//________________________________________________________________

bool GetElemento (const MatrizBit& m, int f, int c)
{
  return m.v[GetColumnas(m)*f + c] == '1';
}

//________________________________________________________________

void SetElemento (MatrizBit& m, int f, int c, bool v)
{
  const int COLS = GetColumnas(m);
  const int FILS = GetFilas(m);

  if (f < FILS && c < COLS && f >= 0 && c >= 0)
    m.v[COLS*f + c] = v ? '1' : '0';
}

/* Fin fichero: matriz_bit3.cpp */
<commit_msg>minnor fixes<commit_after>/**
  * @file matriz_bit3.cpp
  * @brief Implementación de funciones para MatrizBit de tipo 3
  *
  */

const int MAX_POS = 16;

bool Inicializar (MatrizBit& m, int fils, int cols)
{
  bool exito = fils * cols <= m.MAX_ESPACIO && fils >= 0 && cols >= 0;

  if (exito)
  {
    m.espacio = (fils << MAX_POS) | cols;

    for (int i = 0; i < fils * cols; i++)
      m.v[i] = '0';
  }

  return exito;
}

//________________________________________________________________

int GetFilas (const MatrizBit& m)
{
  return m.espacio >> MAX_POS;
}

//________________________________________________________________

int GetColumnas (const MatrizBit& m)
{
  return m.espacio & 0xFFFF;
}
//________________________________________________________________

bool GetElemento (const MatrizBit& m, int f, int c)
{
  return m.v[GetColumnas(m) * f + c];
}

//________________________________________________________________

void SetElemento (MatrizBit& m, int f, int c, bool v)
{
  const int COLS = GetColumnas(m);
  const int FILS = GetFilas(m);

  if (f < FILS && c < COLS && f >= 0 && c >= 0)
    m.v[COLS * f + c] = v ? '1' : '\0';
}

/* Fin fichero: matriz_bit3.cpp */
<|endoftext|>


<commit_before>/*
	A vector implementation by Charles Bailey
	Because sundays are boring.

	12/4/16
*/
#include <stdexcept>

namespace Charlie {

	typedef unsigned int size_t;

	template <typename T>
	class Vector {
		T *stuff;
		size_t actual_size, num_elements;

	  public:
		Vector();
		Vector(size_t _size, T def = T());
		Vector(const Vector<T>& other);
		Vector(Vector<T>&& other);

		void operator=(const Vector<T>& other);
		void operator=(Vector<T>&& other);

		~Vector();

		T& operator[](size_t index);
		const T& operator[](size_t index) const;

		T& at(size_t index);
		const T& at(size_t index) const;

		T& front();
		const T& front() const;

		T& back();
		const T& back() const;

		T* data();
		const T* data() const;

		bool empty() const;

		void push_back(const T& item);
		T pop_back();

		void insert(const int& index , const T& item);

		size_t size() const;
		size_t capacity() const;
		size_t max_size() const;

		void shrink_to_fit();
		void reserve(size_t new_size);

		void resize(size_t count);
		void resize(size_t count , const T& value);
		void assign(size_t count , const T& value);

		void clear();
		void swap(Vector<T>& other);

	  private:

		void _grow();
		void _resize(const size_t& new_size);
	};

	template <typename T>
	Vector<T>::Vector() : actual_size(10), num_elements(0) {
		stuff = new T[actual_size];
	}

	template <typename T>
	Vector<T>::Vector(size_t _size, T def) {
		actual_size = _size;
		stuff = new T[actual_size];

		num_elements = 0;
		while (num_elements < actual_size)
			stuff[num_elements++] = def;
	}

	template <typename T>
	Vector<T>::Vector(const Vector<T>& other) {
		*this = other;
	}

	template <typename T>
	Vector<T>::Vector(Vector<T>&& other) {
		*this = other;
	}

	template <typename T>
	void Vector<T>::operator=(const Vector<T>& other) {
		if (this == &other)
			return;

		actual_size = other.actual_size;
		stuff = new T[actual_size];

		num_elements = 0;
		while(num_elements < other.num_elements) {
			stuff[num_elements] = other.stuff[num_elements];
			num_elements++;
		}
	}

	template <typename T>
	void Vector<T>::operator=(Vector<T>&& other) {
		if (this == &other)
			return;

		actual_size = other.actual_size;
		num_elements = other.num_elements;

		stuff = other.stuff;
		other.stuff = nullptr;
	}

	template <typename T>
	Vector<T>::~Vector() {
		delete [] stuff;
	}

	template <typename T>
	T& Vector<T>::operator[](size_t index) {
		return stuff[index];
	}

	template <typename T>
	const T& Vector<T>::operator[](size_t index) const {
		return stuff[index];
	}

	template <typename T>
	T& Vector<T>::at(size_t index) {
		if (index >= num_elements)
			throw std::out_of_range("That index is out of range.");
		return stuff[index];
	}

	template <typename T>
	const T& Vector<T>::at(size_t index) const {
		if (index >= num_elements)
			throw std::out_of_range("That index is out of range.");
		return stuff[index];
	}

	template <typename T>
	T& Vector<T>::front() {
		return at(0);
	}

	template <typename T>
	const T& Vector<T>::front() const {
		return at(0);
	}

	template <typename T>
	T& Vector<T>::back() {
		return at(num_elements - 1);
	}

	template <typename T>
	const T& Vector<T>::back() const {
		return at(num_elements - 1);
	}

	template <typename T>
	T* Vector<T>::data() {
		return stuff;
	}

	template <typename T>
	const T* Vector<T>::data() const {
		return (const T*)stuff;
	}

	template <typename T>
	bool Vector<T>::empty() const {
		return num_elements == 0;
	}

	template <typename T>
	void Vector<T>::push_back(const T& item) {
		insert(num_elements, item);
	}

	template <typename T>
	T Vector<T>::pop_back() {
		return stuff[--num_elements];
	}

	template <typename T>
	void Vector<T>::insert(const int& index , const T& item) {
		if (num_elements >= actual_size) {
			_grow();
		}

		int curr = num_elements++; /* pay attention to this. I'm too lazy to make it its own line. :) */
		while (--curr >= index) {
			stuff[curr+1] = stuff[curr];
		}
		stuff[ index ] = item;
	}

	template <typename T>
	size_t Vector<T>::size() const {
		return actual_size;
	}

	template <typename T>
	size_t Vector<T>::capacity() const {
		return actual_size;
	}

	template <typename T>
	size_t Vector<T>::max_size() const {
		size_t sz = 0;
		return (sz-1);
	}

	template <typename T>
	void Vector<T>::shrink_to_fit() {
		_resize(num_elements);
	}

	template <typename T>
	void Vector<T>::reserve(size_t new_size) {
		if (new_size > actual_size)
			_resize(actual_size);
	}

	template <typename T>
	void Vector<T>::resize(size_t count) {
		_resize(count);
	}

	template <typename T>
	void Vector<T>::resize(size_t count , const T& value) {
		bool writein = count > actual_size;
		_resize(count);

		if (writein)
			while (num_elements < actual_size)
				stuff[num_elements++] = value;
	}

	template <typename T>
	void Vector<T>::assign(size_t count , const T& value) {
		num_elements = 0;
		resize(count, value);
	}

	template <typename T>
	void Vector<T>::clear() {
		for (size_t i = 0; i < num_elements; i++) {
			stuff[i] = T();
		}
		num_elements = 0;
	}

	template <typename T>
	void Vector<T>::swap(Vector<T>& other) {
		std::swap(this->num_elements , other.num_elements);
		std::swap(this->actual_size , other.actual_size);
		std::swap(this->stuff, other.stuff);
	}

	template <typename T>
	void Vector<T>::_grow() {
		_resize(2 * actual_size + 1);
	}

	template <typename T>
	void Vector<T>::_resize(const size_t& new_size) {
		if (actual_size == new_size)
			return;

		actual_size = new_size;
		T *tmp = new T[actual_size];

		size_t n = actual_size < num_elements ? actual_size : num_elements;
		for (size_t i = 0; i < n; i++)
			tmp[i] = stuff[i];

		delete [] stuff;
		stuff = tmp;
	}

};
<commit_msg>pushing comparison vector work<commit_after>/*
	A vector implementation by Charles Bailey
	Because sundays are boring.

	12/4/16
*/
#include <stdexcept>

namespace Charlie {

	typedef unsigned int size_t;

	template <typename T>
	class Vector {
		T *stuff;
		size_t actual_size, num_elements;

	  public:
		Vector();
		Vector(size_t _size, T def = T());
		Vector(const Vector<T>& other);
		Vector(Vector<T>&& other);

		void operator=(const Vector<T>& other);
		void operator=(Vector<T>&& other);

		~Vector();

		T& operator[](size_t index);
		const T& operator[](size_t index) const;

		T& at(size_t index);
		const T& at(size_t index) const;

		T& front();
		const T& front() const;

		T& back();
		const T& back() const;

		T* data();
		const T* data() const;

		bool empty() const;

		void push_back(const T& item);
		T pop_back();

		void insert(const int& index , const T& item);

		size_t size() const;
		size_t capacity() const;
		size_t max_size() const;

		void shrink_to_fit();
		void reserve(size_t new_size);

		void resize(size_t count);
		void resize(size_t count , const T& value);
		void assign(size_t count , const T& value);

		void clear();
		void swap(Vector<T>& other);

		bool operator==(const Vector<T>& other) const;
		bool operator!=(const Vector<T>& other) const;
		bool operator<=(const Vector<T>& other) const;
		bool operator>=(const Vector<T>& other) const;
		bool operator<(const Vector<T>& other) const;
		bool operator>(const Vector<T>& other) const;

	  private:

		void _grow();
		void _resize(const size_t& new_size);
	};

	template <typename T>
	Vector<T>::Vector() : actual_size(10), num_elements(0) {
		stuff = new T[actual_size];
	}

	template <typename T>
	Vector<T>::Vector(size_t _size, T def) {
		actual_size = _size;
		stuff = new T[actual_size];

		num_elements = 0;
		while (num_elements < actual_size)
			stuff[num_elements++] = def;
	}

	template <typename T>
	Vector<T>::Vector(const Vector<T>& other) {
		*this = other;
	}

	template <typename T>
	Vector<T>::Vector(Vector<T>&& other) {
		*this = other;
	}

	template <typename T>
	void Vector<T>::operator=(const Vector<T>& other) {
		if (this == &other)
			return;

		actual_size = other.actual_size;
		stuff = new T[actual_size];

		num_elements = 0;
		while(num_elements < other.num_elements) {
			stuff[num_elements] = other.stuff[num_elements];
			num_elements++;
		}
	}

	template <typename T>
	void Vector<T>::operator=(Vector<T>&& other) {
		if (this == &other)
			return;

		actual_size = other.actual_size;
		num_elements = other.num_elements;

		stuff = other.stuff;
		other.stuff = nullptr;
	}

	template <typename T>
	Vector<T>::~Vector() {
		delete [] stuff;
	}

	template <typename T>
	T& Vector<T>::operator[](size_t index) {
		return stuff[index];
	}

	template <typename T>
	const T& Vector<T>::operator[](size_t index) const {
		return stuff[index];
	}

	template <typename T>
	T& Vector<T>::at(size_t index) {
		if (index >= num_elements)
			throw std::out_of_range("That index is out of range.");
		return stuff[index];
	}

	template <typename T>
	const T& Vector<T>::at(size_t index) const {
		if (index >= num_elements)
			throw std::out_of_range("That index is out of range.");
		return stuff[index];
	}

	template <typename T>
	T& Vector<T>::front() {
		return at(0);
	}

	template <typename T>
	const T& Vector<T>::front() const {
		return at(0);
	}

	template <typename T>
	T& Vector<T>::back() {
		return at(num_elements - 1);
	}

	template <typename T>
	const T& Vector<T>::back() const {
		return at(num_elements - 1);
	}

	template <typename T>
	T* Vector<T>::data() {
		return stuff;
	}

	template <typename T>
	const T* Vector<T>::data() const {
		return (const T*)stuff;
	}

	template <typename T>
	bool Vector<T>::empty() const {
		return num_elements == 0;
	}

	template <typename T>
	void Vector<T>::push_back(const T& item) {
		insert(num_elements, item);
	}

	template <typename T>
	T Vector<T>::pop_back() {
		return stuff[--num_elements];
	}

	template <typename T>
	void Vector<T>::insert(const int& index , const T& item) {
		if (num_elements >= actual_size) {
			_grow();
		}

		int curr = num_elements++; /* pay attention to this. I'm too lazy to make it its own line. :) */
		while (--curr >= index) {
			stuff[curr+1] = stuff[curr];
		}
		stuff[ index ] = item;
	}

	template <typename T>
	size_t Vector<T>::size() const {
		return actual_size;
	}

	template <typename T>
	size_t Vector<T>::capacity() const {
		return actual_size;
	}

	template <typename T>
	size_t Vector<T>::max_size() const {
		size_t sz = 0;
		return (sz-1);
	}

	template <typename T>
	void Vector<T>::shrink_to_fit() {
		_resize(num_elements);
	}

	template <typename T>
	void Vector<T>::reserve(size_t new_size) {
		if (new_size > actual_size)
			_resize(actual_size);
	}

	template <typename T>
	void Vector<T>::resize(size_t count) {
		_resize(count);
	}

	template <typename T>
	void Vector<T>::resize(size_t count , const T& value) {
		bool writein = count > actual_size;
		_resize(count);

		if (writein)
			while (num_elements < actual_size)
				stuff[num_elements++] = value;
	}

	template <typename T>
	void Vector<T>::assign(size_t count , const T& value) {
		num_elements = 0;
		resize(count, value);
	}

	template <typename T>
	void Vector<T>::clear() {
		for (size_t i = 0; i < num_elements; i++) {
			stuff[i] = T();
		}
		num_elements = 0;
	}

	template <typename T>
	void Vector<T>::swap(Vector<T>& other) {
		std::swap(this->num_elements , other.num_elements);
		std::swap(this->actual_size , other.actual_size);
		std::swap(this->stuff, other.stuff);
	}

	template <typename T>
	bool Vector<T>::operator==(const Vector<T>& other) const {
		if (other.actual_size != this->actual_size) return false;
		for (size_t i = 0; i < this->actual_size; i++) {
			if (other.stuff[i] !+ this->stuff[i])
				return false;
		}
		return true;
	}

	template <typename T>
	bool Vector<T>::operator!=(const Vector<T>& other) const {
		return !(*this == other);
	}

	template <typename T>
	bool Vector<T>::operator<=(const Vector<T>& other) const;

	template <typename T>
	bool Vector<T>::operator>=(const Vector<T>& other) const;

	template <typename T>
	bool Vector<T>::operator<(const Vector<T>& other) const;

	template <typename T>
	bool Vector<T>::operator>(const Vector<T>& other) const;

	template <typename T>
	void Vector<T>::_grow() {
		_resize(2 * actual_size + 1);
	}

	template <typename T>
	void Vector<T>::_resize(const size_t& new_size) {
		if (actual_size == new_size)
			return;

		actual_size = new_size;
		T *tmp = new T[actual_size];

		size_t n = actual_size < num_elements ? actual_size : num_elements;
		for (size_t i = 0; i < n; i++)
			tmp[i] = stuff[i];

		delete [] stuff;
		stuff = tmp;
	}

};
<|endoftext|>


<commit_before>// $Id$

#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <stdlib.h>
#include <assert.h>
#include <time.h>

using namespace std;

#define SAFE_GETLINE(_IS, _LINE, _SIZE, _DELIM) {_IS.getline(_LINE, _SIZE, _DELIM); if(_IS.fail() && !_IS.bad() && !_IS.eof()) _IS.clear();}
#define LINE_MAX_LENGTH 10000

class SentenceAlignment {
 public:
  vector<string> english;
  vector<string> foreign;
  vector<int> alignedCountF;
  vector< vector<int> > alignedToE;

  int create( char[], char[], char[], int );
  //  void clear() { delete(alignment); };
};

void extract( SentenceAlignment & );
void addPhrase( SentenceAlignment &, int, int, int, int );
vector<string> tokenize( char [] );
bool isAligned ( SentenceAlignment &, int, int );

ofstream extractFile;
ofstream extractFileInv;
ofstream extractFileOrientation;
int maxPhraseLength;
int phraseCount = 0;
char* fileNameExtract;
bool orientationFlag;

int main(int argc, char* argv[])
{
  cerr << "PhraseExtract v1.3.0, written by Philipp Koehn\n"
       << "phrase extraction from an aligned parallel corpus\n";
  time_t starttime = time(NULL);

  if (argc != 6 && argc != 7) {
    cerr << "syntax: phrase-extract en de align extract max-length [orientation]\n";
    exit(1);
  }
  char* &fileNameE = argv[1];
  char* &fileNameF = argv[2];
  char* &fileNameA = argv[3];
  fileNameExtract = argv[4];
  maxPhraseLength = atoi(argv[5]);
  orientationFlag = (argc == 7);
  if (orientationFlag) cerr << "(also extracting orientation)\n";

  //  string fileNameE = "/data/nlp/koehn/europarl-v2/models/de-en/model/aligned.en";
  //  string fileNameF = "/data/nlp/koehn/europarl-v2/models/de-en/model/aligned.de";
  //  string fileNameA = "/data/nlp/koehn/europarl-v2/models/de-en/model/aligned.grow-diag-final";

  ifstream eFile;
  ifstream fFile;
  ifstream aFile;
  eFile.open(fileNameE);
  fFile.open(fileNameF);
  aFile.open(fileNameA);
  istream *eFileP = &eFile;
  istream *fFileP = &fFile;
  istream *aFileP = &aFile;

  // string fileNameExtract = "/data/nlp/koehn/europarl-v2/models/de-en/model/new-extract";

  int i=0;
  while(true) {
    i++;
    if (i%10000 == 0) cerr << "." << flush;
    char englishString[LINE_MAX_LENGTH];
    char foreignString[LINE_MAX_LENGTH];
    char alignmentString[LINE_MAX_LENGTH];
    SAFE_GETLINE((*eFileP), englishString, LINE_MAX_LENGTH, '\n');
    if (eFileP->eof()) break;
    SAFE_GETLINE((*fFileP), foreignString, LINE_MAX_LENGTH, '\n');
    SAFE_GETLINE((*aFileP), alignmentString, LINE_MAX_LENGTH, '\n');
    SentenceAlignment sentence;
    // cout << "read in: " << englishString << " & " << foreignString << " & " << alignmentString << endl;
    if (sentence.create( englishString, foreignString, alignmentString, i ))
      extract(sentence);
  }

  eFile.close();
  fFile.close();
  aFile.close();
  extractFile.close();
  extractFileInv.close();
}

void extract( SentenceAlignment &sentence ) {
  int countE = sentence.english.size();
  int countF = sentence.foreign.size();

  // check alignments for english phrase startE...endE
  for(int startE=0;startE<countE;startE++) {
    for(int endE=startE;
	(endE<countE && endE<startE+maxPhraseLength);
	endE++) {

      int minF = 9999;
      int maxF = -1;
      vector< int > usedF = sentence.alignedCountF;
      for(int ei=startE;ei<=endE;ei++) {
	for(int i=0;i<sentence.alignedToE[ei].size();i++) {
	  int fi = sentence.alignedToE[ei][i];
	  // cout << "point (" << fi << ", " << ei << ")\n";
	  if (fi<minF) { minF = fi; }
	  if (fi>maxF) { maxF = fi; }
	  usedF[ fi ]--;
	}
      }

      // cout << "f projected ( " << minF << "-" << maxF << ", " << startE << "," << endE << ")\n";

      if (maxF >= 0 && // aligned to any foreign words at all
	  maxF-minF < maxPhraseLength) { // foreign phrase within limits

	// check if foreign words are aligned to out of bound english words
	bool out_of_bounds = false;
	for(int fi=minF;fi<=maxF && !out_of_bounds;fi++)
	  if (usedF[fi]>0) {
	    // cout << "ouf of bounds: " << fi << "\n";
	    out_of_bounds = true;
	  }

	// cout << "doing if for ( " << minF << "-" << maxF << ", " << startE << "," << endE << ")\n";
	if (!out_of_bounds)
	  // start point of foreign phrase may retreat over unaligned
	  for(int startF=minF;
	      (startF>=0 &&
	       startF>maxF-maxPhraseLength && // within length limit
	       (startF==minF || sentence.alignedCountF[startF]==0)); // unaligned
	      startF--)
	    // end point of foreign phrase may advance over unaligned
	    for(int endF=maxF;
		(endF<countF &&
		 endF<startF+maxPhraseLength && // within length limit
		 (endF==maxF || sentence.alignedCountF[endF]==0)); // unaligned
		endF++)
	      addPhrase(sentence,startE,endE,startF,endF);
      }
    }
  }
}

void addPhrase( SentenceAlignment &sentence, int startE, int endE, int startF, int endF ) {
  // foreign
  // cout << "adding ( " << startF << "-" << endF << ", " << startE << "-" << endE << ")\n";
  if (phraseCount % 10000000 == 0) {
    if (phraseCount>0) {
      extractFile.close();
      extractFileInv.close();
      if (orientationFlag) extractFileOrientation.close();
    }
    char part[10];
    sprintf(part,".part%04d",phraseCount/10000000);
    string fileNameExtractPart = string(fileNameExtract) + part;
    string fileNameExtractInvPart = string(fileNameExtract) + ".inv" + part;
    string fileNameExtractOrientationPart = string(fileNameExtract) + ".o" + part;
    extractFile.open(fileNameExtractPart.c_str());
    extractFileInv.open(fileNameExtractInvPart.c_str());
    if (orientationFlag) extractFileOrientation.open(fileNameExtractOrientationPart.c_str());
  }
  phraseCount++;

  for(int fi=startF;fi<=endF;fi++) {
    extractFile << sentence.foreign[fi] << " ";
    if (orientationFlag) extractFileOrientation << sentence.foreign[fi] << " ";
  }
  extractFile << "||| ";
  if (orientationFlag) extractFileOrientation << "||| ";

  // english
  for(int ei=startE;ei<=endE;ei++) {
    extractFile << sentence.english[ei] << " ";
    extractFileInv << sentence.english[ei] << " ";
    if (orientationFlag) extractFileOrientation << sentence.english[ei] << " ";
  }
  extractFile << "|||";
  extractFileInv << "||| ";
  if (orientationFlag) extractFileOrientation << "||| ";

  // foreign (for inverse)
  for(int fi=startF;fi<=endF;fi++)
    extractFileInv << sentence.foreign[fi] << " ";
  extractFileInv << "|||";

  // alignment
  for(int ei=startE;ei<=endE;ei++)
    for(int i=0;i<sentence.alignedToE[ei].size();i++) {
      int fi = sentence.alignedToE[ei][i];
      extractFile << " " << fi-startF << "-" << ei-startE;
      extractFileInv << " " << ei-startE << "-" << fi-startF;
    }

  if (orientationFlag) {

    // orientation to previous E
    bool connectedLeftTop  = isAligned( sentence, startF-1, startE-1 );
    bool connectedRightTop = isAligned( sentence, endF+1,   startE-1 );
    if      ( connectedLeftTop && !connectedRightTop)
      extractFileOrientation << "mono";
    else if (!connectedLeftTop &&  connectedRightTop)
      extractFileOrientation << "swap";
    else
      extractFileOrientation << "other";

    // orientation to following E
    bool connectedLeftBottom  = isAligned( sentence, startF-1, endE+1 );
    bool connectedRightBottom = isAligned( sentence, endF+1,   endE+1 );
    if      ( connectedLeftBottom && !connectedRightBottom)
      extractFileOrientation << " swap";
    else if (!connectedLeftBottom &&  connectedRightBottom)
      extractFileOrientation << " mono";
    else
      extractFileOrientation << " other";
  }

  extractFile << "\n";
  extractFileInv << "\n";
  if (orientationFlag) extractFileOrientation << "\n";
}

bool isAligned ( SentenceAlignment &sentence, int fi, int ei ) {
  if (ei == -1 && fi == -1) return true;
  if (ei <= -1 || fi <= -1) return false;
  if (ei == sentence.english.size() && fi == sentence.foreign.size()) return true;
  if (ei >= sentence.english.size() || fi >= sentence.foreign.size()) return false;
  for(int i=0;i<sentence.alignedToE[ei].size();i++)
    if (sentence.alignedToE[ei][i] == fi) return true;
  return false;
}

int SentenceAlignment::create( char englishString[], char foreignString[], char alignmentString[], int sentenceID ) {
  english = tokenize( englishString );
  foreign = tokenize( foreignString );
  //  alignment = new bool[foreign.size()*english.size()];
  //  alignment = (bool**) calloc(english.size()*foreign.size(),sizeof(bool)); // is this right?

  if (english.size() == 0 || foreign.size() == 0) {
    cerr << "no english (" << english.size() << ") or foreign (" << foreign.size() << ") words << end insentence " << sentenceID << endl;
    cerr << "E: " << englishString << endl << "F: " << foreignString << endl;
    return 0;
  }
  // cout << "english.size = " << english.size() << endl;
  // cout << "foreign.size = " << foreign.size() << endl;

  // cout << "xxx\n";
  for(int i=0; i<foreign.size(); i++) {
    // cout << "i" << i << endl;
    alignedCountF.push_back( 0 );
  }
  for(int i=0; i<english.size(); i++) {
    vector< int > dummy;
    alignedToE.push_back( dummy );
  }
  // cout << "\nscanning...\n";

  vector<string> alignmentSequence = tokenize( alignmentString );
  for(int i=0; i<alignmentSequence.size(); i++) {
    int e,f;
    // cout << "scaning " << alignmentSequence[i].c_str() << endl;
    if (! sscanf(alignmentSequence[i].c_str(), "%d-%d", &f, &e)) {
      cerr << "WARNING: " << alignmentSequence[i] << " is a bad alignment point in sentnce " << sentenceID << endl;
      cerr << "E: " << englishString << endl << "F: " << foreignString << endl;
      return 0;
    }
      // cout << "alignmentSequence[i] " << alignmentSequence[i] << " is " << f << ", " << e << endl;
    if (e >= english.size() || f >= foreign.size()) {
      cerr << "WARNING: sentence " << sentenceID << " has alignment point (" << f << ", " << e << ") out of bounds (" << foreign.size() << ", " << english.size() << ")\n";
      cerr << "E: " << englishString << endl << "F: " << foreignString << endl;
      return 0;
    }
    alignedToE[e].push_back( f );
    alignedCountF[f]++;
  }
  return 1;
}

<commit_msg>andreas zollman's changes to write span information<commit_after>// $Id$

#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <stdlib.h>
#include <assert.h>
#include <time.h>

using namespace std;

#define SAFE_GETLINE(_IS, _LINE, _SIZE, _DELIM) {_IS.getline(_LINE, _SIZE, _DELIM); if(_IS.fail() && !_IS.bad() && !_IS.eof()) _IS.clear();}
#define LINE_MAX_LENGTH 10000

class SentenceAlignment {
 public:
  vector<string> english;
  vector<string> foreign;
  vector<int> alignedCountF;
  vector< vector<int> > alignedToE;

  int create( char[], char[], char[], int );
  //  void clear() { delete(alignment); };
};

void extract( SentenceAlignment & );
void addPhrase( SentenceAlignment &, int, int, int, int );
vector<string> tokenize( char [] );
bool isAligned ( SentenceAlignment &, int, int );

ofstream extractFile;
ofstream extractFileInv;
ofstream extractFileOrientation;
int maxPhraseLength;
int phraseCount = 0;
char* fileNameExtract;
bool orientationFlag;
bool onlyOutputSpanInfo;

int main(int argc, char* argv[])
{
  cerr << "PhraseExtract v1.3.0, written by Philipp Koehn\n"
       << "phrase extraction from an aligned parallel corpus\n";
  time_t starttime = time(NULL);

  if (argc != 6 && argc != 7) {
    cerr << "syntax: phrase-extract en de align extract max-length [orientation | --OnlyOutputSpanInfo]\n";
    exit(1);
  }
  char* &fileNameE = argv[1];
  char* &fileNameF = argv[2];
  char* &fileNameA = argv[3];
  fileNameExtract = argv[4];
  maxPhraseLength = atoi(argv[5]);
  onlyOutputSpanInfo = argc == 7 && strcmp(argv[6],"--OnlyOutputSpanInfo") == 0; //az
  if (onlyOutputSpanInfo) cerr << "Only outputting span info in format (starting from 0): SrcBegin SrcEnd TgtBegin TgtEnd\n"; //az
  orientationFlag = (argc == 7 && !onlyOutputSpanInfo);
  if (orientationFlag) cerr << "(also extracting orientation)\n";

  //  string fileNameE = "/data/nlp/koehn/europarl-v2/models/de-en/model/aligned.en";
  //  string fileNameF = "/data/nlp/koehn/europarl-v2/models/de-en/model/aligned.de";
  //  string fileNameA = "/data/nlp/koehn/europarl-v2/models/de-en/model/aligned.grow-diag-final";

  ifstream eFile;
  ifstream fFile;
  ifstream aFile;
  eFile.open(fileNameE);
  fFile.open(fileNameF);
  aFile.open(fileNameA);
  istream *eFileP = &eFile;
  istream *fFileP = &fFile;
  istream *aFileP = &aFile;

  // string fileNameExtract = "/data/nlp/koehn/europarl-v2/models/de-en/model/new-extract";

  int i=0;
  while(true) {
    i++;
    if (i%10000 == 0) cerr << "." << flush;
    char englishString[LINE_MAX_LENGTH];
    char foreignString[LINE_MAX_LENGTH];
    char alignmentString[LINE_MAX_LENGTH];
    SAFE_GETLINE((*eFileP), englishString, LINE_MAX_LENGTH, '\n');
    if (eFileP->eof()) break;
    SAFE_GETLINE((*fFileP), foreignString, LINE_MAX_LENGTH, '\n');
    SAFE_GETLINE((*aFileP), alignmentString, LINE_MAX_LENGTH, '\n');
    SentenceAlignment sentence;
    // cout << "read in: " << englishString << " & " << foreignString << " & " << alignmentString << endl;
    //az: output src, tgt, and alingment line
    if (onlyOutputSpanInfo) {
      cout << "LOG: SRC: " << foreignString << endl;
      cout << "LOG: TGT: " << englishString << endl;
      cout << "LOG: ALT: " << alignmentString << endl;
      cout << "LOG: PHRASES_BEGIN:" << endl;
    }

    if (sentence.create( englishString, foreignString, alignmentString, i ))
      extract(sentence);
    if (onlyOutputSpanInfo) cout << "LOG: PHRASES_END:" << endl; //az: mark end of phrases
  }

  eFile.close();
  fFile.close();
  aFile.close();
  //az: only close if we actually opened it
  if (!onlyOutputSpanInfo) {
    extractFile.close();
    extractFileInv.close();
    if (orientationFlag) extractFileOrientation.close();
  }
}

void extract( SentenceAlignment &sentence ) {
  int countE = sentence.english.size();
  int countF = sentence.foreign.size();

  // check alignments for english phrase startE...endE
  for(int startE=0;startE<countE;startE++) {
    for(int endE=startE;
	(endE<countE && endE<startE+maxPhraseLength);
	endE++) {

      int minF = 9999;
      int maxF = -1;
      vector< int > usedF = sentence.alignedCountF;
      for(int ei=startE;ei<=endE;ei++) {
	for(int i=0;i<sentence.alignedToE[ei].size();i++) {
	  int fi = sentence.alignedToE[ei][i];
	  // cout << "point (" << fi << ", " << ei << ")\n";
	  if (fi<minF) { minF = fi; }
	  if (fi>maxF) { maxF = fi; }
	  usedF[ fi ]--;
	}
      }

      // cout << "f projected ( " << minF << "-" << maxF << ", " << startE << "," << endE << ")\n";

      if (maxF >= 0 && // aligned to any foreign words at all
	  maxF-minF < maxPhraseLength) { // foreign phrase within limits

	// check if foreign words are aligned to out of bound english words
	bool out_of_bounds = false;
	for(int fi=minF;fi<=maxF && !out_of_bounds;fi++)
	  if (usedF[fi]>0) {
	    // cout << "ouf of bounds: " << fi << "\n";
	    out_of_bounds = true;
	  }

	// cout << "doing if for ( " << minF << "-" << maxF << ", " << startE << "," << endE << ")\n";
	if (!out_of_bounds)
	  // start point of foreign phrase may retreat over unaligned
	  for(int startF=minF;
	      (startF>=0 &&
	       startF>maxF-maxPhraseLength && // within length limit
	       (startF==minF || sentence.alignedCountF[startF]==0)); // unaligned
	      startF--)
	    // end point of foreign phrase may advance over unaligned
	    for(int endF=maxF;
		(endF<countF &&
		 endF<startF+maxPhraseLength && // within length limit
		 (endF==maxF || sentence.alignedCountF[endF]==0)); // unaligned
		endF++)
	      addPhrase(sentence,startE,endE,startF,endF);
      }
    }
  }
}

void addPhrase( SentenceAlignment &sentence, int startE, int endE, int startF, int endF ) {
  // foreign
  // cout << "adding ( " << startF << "-" << endF << ", " << startE << "-" << endE << ")\n";

 if (onlyOutputSpanInfo) {
   cout << startF << " " << endF << " " << startE << " " << endE << endl;
 } else {

  if (phraseCount % 10000000 == 0) {
    if (phraseCount>0) {
      extractFile.close();
      extractFileInv.close();
      if (orientationFlag) extractFileOrientation.close();
    }
    char part[10];
    sprintf(part,".part%04d",phraseCount/10000000);
    string fileNameExtractPart = string(fileNameExtract) + part;
    string fileNameExtractInvPart = string(fileNameExtract) + ".inv" + part;
    string fileNameExtractOrientationPart = string(fileNameExtract) + ".o" + part;
    extractFile.open(fileNameExtractPart.c_str());
    extractFileInv.open(fileNameExtractInvPart.c_str());
    if (orientationFlag) extractFileOrientation.open(fileNameExtractOrientationPart.c_str());
  }
  phraseCount++;

  for(int fi=startF;fi<=endF;fi++) {
    extractFile << sentence.foreign[fi] << " ";
    if (orientationFlag) extractFileOrientation << sentence.foreign[fi] << " ";
  }
  extractFile << "||| ";
  if (orientationFlag) extractFileOrientation << "||| ";

  // english
  for(int ei=startE;ei<=endE;ei++) {
    extractFile << sentence.english[ei] << " ";
    extractFileInv << sentence.english[ei] << " ";
    if (orientationFlag) extractFileOrientation << sentence.english[ei] << " ";
  }
  extractFile << "|||";
  extractFileInv << "||| ";
  if (orientationFlag) extractFileOrientation << "||| ";

  // foreign (for inverse)
  for(int fi=startF;fi<=endF;fi++)
    extractFileInv << sentence.foreign[fi] << " ";
  extractFileInv << "|||";

  // alignment
  for(int ei=startE;ei<=endE;ei++)
    for(int i=0;i<sentence.alignedToE[ei].size();i++) {
      int fi = sentence.alignedToE[ei][i];
      extractFile << " " << fi-startF << "-" << ei-startE;
      extractFileInv << " " << ei-startE << "-" << fi-startF;
    }

  if (orientationFlag) {

    // orientation to previous E
    bool connectedLeftTop  = isAligned( sentence, startF-1, startE-1 );
    bool connectedRightTop = isAligned( sentence, endF+1,   startE-1 );
    if      ( connectedLeftTop && !connectedRightTop)
      extractFileOrientation << "mono";
    else if (!connectedLeftTop &&  connectedRightTop)
      extractFileOrientation << "swap";
    else
      extractFileOrientation << "other";

    // orientation to following E
    bool connectedLeftBottom  = isAligned( sentence, startF-1, endE+1 );
    bool connectedRightBottom = isAligned( sentence, endF+1,   endE+1 );
    if      ( connectedLeftBottom && !connectedRightBottom)
      extractFileOrientation << " swap";
    else if (!connectedLeftBottom &&  connectedRightBottom)
      extractFileOrientation << " mono";
    else
      extractFileOrientation << " other";
  }

  extractFile << "\n";
  extractFileInv << "\n";
  if (orientationFlag) extractFileOrientation << "\n";
 } // end: if (onlyOutputSpanInfo)
}

bool isAligned ( SentenceAlignment &sentence, int fi, int ei ) {
  if (ei == -1 && fi == -1) return true;
  if (ei <= -1 || fi <= -1) return false;
  if (ei == sentence.english.size() && fi == sentence.foreign.size()) return true;
  if (ei >= sentence.english.size() || fi >= sentence.foreign.size()) return false;
  for(int i=0;i<sentence.alignedToE[ei].size();i++)
    if (sentence.alignedToE[ei][i] == fi) return true;
  return false;
}

int SentenceAlignment::create( char englishString[], char foreignString[], char alignmentString[], int sentenceID ) {
  english = tokenize( englishString );
  foreign = tokenize( foreignString );
  //  alignment = new bool[foreign.size()*english.size()];
  //  alignment = (bool**) calloc(english.size()*foreign.size(),sizeof(bool)); // is this right?

  if (english.size() == 0 || foreign.size() == 0) {
    cerr << "no english (" << english.size() << ") or foreign (" << foreign.size() << ") words << end insentence " << sentenceID << endl;
    cerr << "E: " << englishString << endl << "F: " << foreignString << endl;
    return 0;
  }
  // cout << "english.size = " << english.size() << endl;
  // cout << "foreign.size = " << foreign.size() << endl;

  // cout << "xxx\n";
  for(int i=0; i<foreign.size(); i++) {
    // cout << "i" << i << endl;
    alignedCountF.push_back( 0 );
  }
  for(int i=0; i<english.size(); i++) {
    vector< int > dummy;
    alignedToE.push_back( dummy );
  }
  // cout << "\nscanning...\n";

  vector<string> alignmentSequence = tokenize( alignmentString );
  for(int i=0; i<alignmentSequence.size(); i++) {
    int e,f;
    // cout << "scaning " << alignmentSequence[i].c_str() << endl;
    if (! sscanf(alignmentSequence[i].c_str(), "%d-%d", &f, &e)) {
      cerr << "WARNING: " << alignmentSequence[i] << " is a bad alignment point in sentnce " << sentenceID << endl;
      cerr << "E: " << englishString << endl << "F: " << foreignString << endl;
      return 0;
    }
      // cout << "alignmentSequence[i] " << alignmentSequence[i] << " is " << f << ", " << e << endl;
    if (e >= english.size() || f >= foreign.size()) {
      cerr << "WARNING: sentence " << sentenceID << " has alignment point (" << f << ", " << e << ") out of bounds (" << foreign.size() << ", " << english.size() << ")\n";
      cerr << "E: " << englishString << endl << "F: " << foreignString << endl;
      return 0;
    }
    alignedToE[e].push_back( f );
    alignedCountF[f]++;
  }
  return 1;
}

<|endoftext|>


<commit_before><commit_msg>Fix other tile sizes<commit_after><|endoftext|>


<commit_before>#include "ROOT/RTaskArena.hxx"
#include "TError.h"
#include "TROOT.h"
#include "TThread.h"
#include <fstream>
#include <sys/stat.h>
#include <thread>
#include "tbb/task_arena.h"

//////////////////////////////////////////////////////////////////////////
///
/// \class ROOT::Internal::RTaskArenaWrapper
/// \ingroup Parallelism
/// \brief Wrapper over tbb::task_arena
///
/// This class is a wrapper over tbb::task_arena, in order to keep
/// TBB away from ROOT's headers. We keep a single global instance,
/// obtained with `ROOT::Internal::GetGlobalTaskArena()`, to be used by any
/// parallel ROOT class with TBB as a backend. This has several advantages:
///
///   - Provides a unique interface to the TBB scheduler: TThreadExecutor,
///     IMT and any class relying on TBB will get a pointer to the scheduler
///     through `ROOT::Internal::GetGlobalTaskArena()`, which will return a
///     reference to the only pointer to the TBB scheduler that will be
///     active in any ROOT Process
///   - Solves multiple undefined behaviors. Guaranteeing that all classes
///    use the same task arena avoids interferences and undefined behavior
///    by providing a single instance of the tbb::task_arena and automated
///    bookkeeping, instantiation and destruction.
///
/// #### Examples:
/// ~~~{.cpp}
/// root[] auto gTA = ROOT::Internal::GetGlobalTaskArena() //get a shared_ptr to the global arena
/// root[] gTA->InitGlobalTaskArena(nWorkers) // Initialize the global arena and enable Thread Safety in ROOT
/// root[] gTA->TaskArenaSize() // Get the current size of the arena (number of worker threads)
/// root[] gTA->Access() //std::unique_ptr to the internal tbb::task_arena for interacting directly with it (needed to call operations such as execute)
/// root[] root[] gTA->Access()->max_concurrency() // call to tbb::task_arena::max_concurrency()
/// ~~~
///
//////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// Returns the available number of logical cores.
///
///  - Checks if there is CFS bandwidth control in place (linux, via cgroups,
///    assuming standard paths)
///  - Otherwise, returns the number of logical cores provided by
///    std::thread::hardware_concurrency()
////////////////////////////////////////////////////////////////////////////////
static Int_t LogicalCPUBandwithControl()
{
#ifdef R__LINUX
   // Check for CFS bandwith control
   std::ifstream f;
   std::string quotaFile("/sys/fs/cgroup/cpuacct/cpu.cfs_quota_us");
   struct stat buffer;
   // Does the file exist?
   if(stat(quotaFile.c_str(), &buffer) == 0) {
      f.open(quotaFile);
      float cfs_quota;
      f>>cfs_quota;
      f.close();
      if(cfs_quota > 0) {
         std::string periodFile("/sys/fs/cgroup/cpuacct/cpu.cfs_period_us");
         f.open(periodFile);
         float cfs_period;
         f>>cfs_period;
         f.close();
         return static_cast<int>(std::ceil(cfs_quota/cfs_period));
      }
   }
#endif
   return std::thread::hardware_concurrency();
}

namespace ROOT{
namespace Internal {

////////////////////////////////////////////////////////////////////////////////
/// Initializes the tbb::task_arena within RTaskArenaWrapper
///
/// * Can't be reinitialized
/// * Checks for CPU bandwidth control and avoids oversubscribing
/// * If no BC in place and maxConcurrency<1, defaults to the default tbb number of threads,
/// which is CPU affinity aware
////////////////////////////////////////////////////////////////////////////////
RTaskArenaWrapper::RTaskArenaWrapper(unsigned maxConcurrency): fTBBArena(new tbb::task_arena{})
{
   if (!fTBBArena->is_active()) {
      unsigned tbbDefaultNumberThreads = fTBBArena->max_concurrency(); // not initialized, automatic state
      maxConcurrency = maxConcurrency > 0 ? std::min(maxConcurrency, tbbDefaultNumberThreads) : tbbDefaultNumberThreads;
      unsigned bcCpus = LogicalCPUBandwithControl();
      if (maxConcurrency>bcCpus) {
         Warning("RTaskArenaWrapper", "CPU Bandwith Control Active. Proceeding with %d threads accordingly",
            bcCpus);
         maxConcurrency = bcCpus;
      }
      fTBBArena->initialize(maxConcurrency);
      fNWorkers = maxConcurrency;
      ROOT::EnableThreadSafety();
   } else {
      unsigned current = fTBBArena->max_concurrency();
      if (maxConcurrency && (current != maxConcurrency)) {
         Warning("RTaskArenaWrapper", "There's already an active task arena. Proceeding with the current %d threads",
            current);
      }
   }
}

RTaskArenaWrapper::~RTaskArenaWrapper()
{
   fNWorkers = 0u;
}

unsigned RTaskArenaWrapper::fNWorkers = 0u;

unsigned RTaskArenaWrapper::TaskArenaSize()
{
   return fNWorkers;
}
////////////////////////////////////////////////////////////////////////////////
/// Provides access to the wrapped tbb::task_arena
////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<tbb::task_arena> &RTaskArenaWrapper::Access()
{
   return fTBBArena;
}

std::shared_ptr<ROOT::Internal::RTaskArenaWrapper> GetGlobalTaskArena(unsigned maxConcurrency)
{
   static std::weak_ptr<ROOT::Internal::RTaskArenaWrapper> weak_GTAWrapper;
   if (weak_GTAWrapper.expired()) {
      std::shared_ptr<ROOT::Internal::RTaskArenaWrapper> shared_GTAWrapper(new ROOT::Internal::RTaskArenaWrapper(maxConcurrency));
      weak_GTAWrapper = shared_GTAWrapper;
      return weak_GTAWrapper.lock();
   }

   return weak_GTAWrapper.lock();
}

} // namespace Internal
} // namespace ROOT
<commit_msg>make variables const<commit_after>#include "ROOT/RTaskArena.hxx"
#include "TError.h"
#include "TROOT.h"
#include "TThread.h"
#include <fstream>
#include <sys/stat.h>
#include <thread>
#include "tbb/task_arena.h"

//////////////////////////////////////////////////////////////////////////
///
/// \class ROOT::Internal::RTaskArenaWrapper
/// \ingroup Parallelism
/// \brief Wrapper over tbb::task_arena
///
/// This class is a wrapper over tbb::task_arena, in order to keep
/// TBB away from ROOT's headers. We keep a single global instance,
/// obtained with `ROOT::Internal::GetGlobalTaskArena()`, to be used by any
/// parallel ROOT class with TBB as a backend. This has several advantages:
///
///   - Provides a unique interface to the TBB scheduler: TThreadExecutor,
///     IMT and any class relying on TBB will get a pointer to the scheduler
///     through `ROOT::Internal::GetGlobalTaskArena()`, which will return a
///     reference to the only pointer to the TBB scheduler that will be
///     active in any ROOT Process
///   - Solves multiple undefined behaviors. Guaranteeing that all classes
///    use the same task arena avoids interferences and undefined behavior
///    by providing a single instance of the tbb::task_arena and automated
///    bookkeeping, instantiation and destruction.
///
/// #### Examples:
/// ~~~{.cpp}
/// root[] auto gTA = ROOT::Internal::GetGlobalTaskArena() //get a shared_ptr to the global arena
/// root[] gTA->InitGlobalTaskArena(nWorkers) // Initialize the global arena and enable Thread Safety in ROOT
/// root[] gTA->TaskArenaSize() // Get the current size of the arena (number of worker threads)
/// root[] gTA->Access() //std::unique_ptr to the internal tbb::task_arena for interacting directly with it (needed to call operations such as execute)
/// root[] root[] gTA->Access()->max_concurrency() // call to tbb::task_arena::max_concurrency()
/// ~~~
///
//////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// Returns the available number of logical cores.
///
///  - Checks if there is CFS bandwidth control in place (linux, via cgroups,
///    assuming standard paths)
///  - Otherwise, returns the number of logical cores provided by
///    std::thread::hardware_concurrency()
////////////////////////////////////////////////////////////////////////////////
static Int_t LogicalCPUBandwithControl()
{
#ifdef R__LINUX
   // Check for CFS bandwith control
   std::ifstream f;
   std::string quotaFile("/sys/fs/cgroup/cpuacct/cpu.cfs_quota_us");
   struct stat buffer;
   // Does the file exist?
   if(stat(quotaFile.c_str(), &buffer) == 0) {
      f.open(quotaFile);
      float cfs_quota;
      f>>cfs_quota;
      f.close();
      if(cfs_quota > 0) {
         std::string periodFile("/sys/fs/cgroup/cpuacct/cpu.cfs_period_us");
         f.open(periodFile);
         float cfs_period;
         f>>cfs_period;
         f.close();
         return static_cast<int>(std::ceil(cfs_quota/cfs_period));
      }
   }
#endif
   return std::thread::hardware_concurrency();
}

namespace ROOT{
namespace Internal {

////////////////////////////////////////////////////////////////////////////////
/// Initializes the tbb::task_arena within RTaskArenaWrapper
///
/// * Can't be reinitialized
/// * Checks for CPU bandwidth control and avoids oversubscribing
/// * If no BC in place and maxConcurrency<1, defaults to the default tbb number of threads,
/// which is CPU affinity aware
////////////////////////////////////////////////////////////////////////////////
RTaskArenaWrapper::RTaskArenaWrapper(unsigned maxConcurrency): fTBBArena(new tbb::task_arena{})
{
   if (!fTBBArena->is_active()) {
      const unsigned tbbDefaultNumberThreads = fTBBArena->max_concurrency(); // not initialized, automatic state
      maxConcurrency = maxConcurrency > 0 ? std::min(maxConcurrency, tbbDefaultNumberThreads) : tbbDefaultNumberThreads;
      const unsigned bcCpus = LogicalCPUBandwithControl();
      if (maxConcurrency>bcCpus) {
         Warning("RTaskArenaWrapper", "CPU Bandwith Control Active. Proceeding with %d threads accordingly",
            bcCpus);
         maxConcurrency = bcCpus;
      }
      fTBBArena->initialize(maxConcurrency);
      fNWorkers = maxConcurrency;
      ROOT::EnableThreadSafety();
   } else {
      const unsigned current = fTBBArena->max_concurrency();
      if (maxConcurrency && (current != maxConcurrency)) {
         Warning("RTaskArenaWrapper", "There's already an active task arena. Proceeding with the current %d threads",
            current);
      }
   }
}

RTaskArenaWrapper::~RTaskArenaWrapper()
{
   fNWorkers = 0u;
}

unsigned RTaskArenaWrapper::fNWorkers = 0u;

unsigned RTaskArenaWrapper::TaskArenaSize()
{
   return fNWorkers;
}
////////////////////////////////////////////////////////////////////////////////
/// Provides access to the wrapped tbb::task_arena
////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<tbb::task_arena> &RTaskArenaWrapper::Access()
{
   return fTBBArena;
}

std::shared_ptr<ROOT::Internal::RTaskArenaWrapper> GetGlobalTaskArena(unsigned maxConcurrency)
{
   static std::weak_ptr<ROOT::Internal::RTaskArenaWrapper> weak_GTAWrapper;
   if (weak_GTAWrapper.expired()) {
      std::shared_ptr<ROOT::Internal::RTaskArenaWrapper> shared_GTAWrapper(new ROOT::Internal::RTaskArenaWrapper(maxConcurrency));
      weak_GTAWrapper = shared_GTAWrapper;
      return weak_GTAWrapper.lock();
   }

   return weak_GTAWrapper.lock();
}

} // namespace Internal
} // namespace ROOT
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <unistd.h>
using namespace std;

#include "tinyxml2/tinyxml2.h"
using namespace tinyxml2;

#include "pretty_printer.h"

/*
 * Usage:
 * 	$ pp "xml string"
 * 	$ xml_output_program | pp
 */

int main(int argc, char* argv[]) {

	/*
	 * No args.
	 * Read XML input from STDIN (used for piping)
	 */
	if(argc == 1) {
    FILE* fp = stdin;
    if(!isatty(fileno(fp))){ //Check STDIN for input
			string str;
			char temp;
			while(!cin.eof()) { //Iterate file pointer until EOF
				cin.get(temp); //Get char
				str += temp; //append char to data string
			}
			print_xml(str.c_str()); //convert str to const char*, format, & print
    } else { //pp called with no args & no data on STDIN
    	arg_error();
		}
	}

	/*
	 * Single argument should be XML data
	 */
	else if(argc == 2) {
		print_xml(argv[1]); //format & print argument
	} else { //Something else
		arg_error();
	}
}

/*
 * Outputs "usage" message
 */
void arg_error(void) {
	cout << "Argument error, check the README.\nUsage:\n";
	cout << "\tpp \"<Hello>World</Hello>\"\n\tprogram_outputs_xml args | pp\n";
}

/*
 * Formats and prints document
 * Yay tinyxml2!
 */
void print_xml(const char* cstr) {
	XMLDocument doc;
	XMLPrinter printer;

	if (doc.Parse(cstr) == XML_SUCCESS) {
		XMLPrinter printer;
		doc.Print(&printer);
		cout << printer.CStr();
	} else {
		cout << "Error parsing XML document.\n";
	}
}
<commit_msg>Fix'd formatting?<commit_after>#include <iostream>
#include <string>
#include <unistd.h>
using namespace std;

#include "tinyxml2/tinyxml2.h"
using namespace tinyxml2;

#include "pretty_printer.h"

/*
 * Usage:
 * 	$ pp "xml string"
 * 	$ xml_output_program | pp
 */

int main(int argc, char* argv[]) {

	/*
	 * No args.
	 * Read XML input from STDIN (used for piping)
	 */
	if(argc == 1) {
		FILE* fp = stdin;
		if(!isatty(fileno(fp))){ //Check STDIN for input
			string str;
			char temp;
			while(!cin.eof()) { //Iterate file pointer until EOF
				cin.get(temp); //Get char
				str += temp; //append char to data string
			}
			print_xml(str.c_str()); //convert str to const char*, format, & print
		} else { //pp called with no args & no data on STDIN
			arg_error();
		}
	}

	/*
	 * Single argument should be XML data
	 */
	else if(argc == 2) {
		print_xml(argv[1]); //format & print argument
	} else { //Something else
		arg_error();
	}
}

/*
 * Outputs "usage" message
 */
void arg_error(void) {
	cout << "Argument error, check the README.\nUsage:\n";
	cout << "\tpp \"<Hello>World</Hello>\"\n\tprogram_outputs_xml args | pp\n";
}

/*
 * Formats and prints document
 * Yay tinyxml2!
 */
void print_xml(const char* cstr) {
	XMLDocument doc;
	XMLPrinter printer;

	if (doc.Parse(cstr) == XML_SUCCESS) {
		XMLPrinter printer;
		doc.Print(&printer);
		cout << printer.CStr();
	} else {
		cout << "Error parsing XML document.\n";
	}
}
<|endoftext|>