<commit_before>/*
 *
 * EthereumLikeTransactionDatabaseHelper
 *
 * Created by El Khalil Bellakrid on 14/07/2018.
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 Ledger
 *
 * 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.
 *
 */

#include "EthereumLikeTransactionDatabaseHelper.h"
#include <math/BigInt.h>
#include <utils/hex.h>
#include <database/soci-option.h>
#include <database/soci-date.h>
#include <database/soci-number.h>
#include <crypto/SHA256.hpp>
#include <wallet/common/database/BlockDatabaseHelper.h>

using namespace soci;

namespace ledger {
    namespace core {

        bool EthereumLikeTransactionDatabaseHelper::getTransactionByHash(soci::session &sql,
                                                                         const std::string &hash,
                                                                         EthereumLikeBlockchainExplorerTransaction &tx) {

            rowset<row> rows = (sql.prepare << "SELECT  tx.hash, tx.value, tx.nonce, tx.time, tx.input_data, tx.gas_price, "
                                                "tx.gas_limit, tx.gas_used, tx.sender, tx.receiver, tx.confirmations, tx.status, "
                                                "block.hash, block.height, block.time, block.currency_name "
                                                "FROM ethereum_transactions AS tx "
                                                "LEFT JOIN blocks AS block ON tx.block_uid = block.uid "
                                                "WHERE tx.hash = :hash", use(hash));

            for (auto& row : rows) {
                inflateTransaction(sql, row, tx);
                return true;
            }

            return false;
        }

        bool EthereumLikeTransactionDatabaseHelper::inflateTransaction(soci::session &sql,
                                                                       const soci::row &row,
                                                                       EthereumLikeBlockchainExplorerTransaction &tx) {
            tx.hash = row.get<std::string>(0);
            tx.value = BigInt::fromHex(row.get<std::string>(1));
            auto nonceBytes = hex::toByteArray(row.get<std::string>(2));
            auto shift = 0;
            for (auto& byte : nonceBytes) {
                tx.nonce += byte << shift;
                shift += 8;
            }

            tx.receivedAt = row.get<std::chrono::system_clock::time_point>(3);
            tx.inputData = hex::toByteArray(row.get<std::string>(4));

            tx.gasPrice = BigInt::fromHex(row.get<std::string>(5));
            tx.gasLimit = BigInt::fromHex(row.get<std::string>(6));
            tx.gasUsed = BigInt::fromHex(row.get<std::string>(7));

            tx.receiver = row.get<std::string>(8);
            tx.sender = row.get<std::string>(9);

            tx.confirmations = get_number<uint64_t>(row, 10);
            tx.status = get_number<uint64_t>(row, 11);
            if (row.get_indicator(12) != i_null) {
                EthereumLikeBlockchainExplorer::Block block;
                block.hash = row.get<std::string>(12);
                block.height = get_number<uint64_t>(row, 13);
                block.time = row.get<std::chrono::system_clock::time_point>(14);
                block.currencyName = row.get<std::string>(15);
                tx.block = block;
            }

            return true;
        }

        bool EthereumLikeTransactionDatabaseHelper::transactionExists(soci::session &sql,
                                                                      const std::string &ethTxUid) {
            int32_t count = 0;
            sql << "SELECT COUNT(*) FROM ethereum_transactions WHERE transaction_uid = :ethTxUid", use(ethTxUid), into(count);
            return count == 1;
        }

        std::string EthereumLikeTransactionDatabaseHelper::createEthereumTransactionUid(const std::string& accountUid,
                                                                                const std::string& txHash) {
            auto result = SHA256::stringToHexHash(fmt::format("uid:{}+{}", accountUid, txHash));
            return result;
        }

        std::string EthereumLikeTransactionDatabaseHelper::putTransaction(soci::session &sql,
                                                                         const std::string& accountUid,
                                                                         const EthereumLikeBlockchainExplorerTransaction &tx) {
            auto blockUid = tx.block.map<std::string>([] (const EthereumLikeBlockchainExplorer::Block& block) {
                return block.getUid();
            });

            auto ethTxUid = createEthereumTransactionUid(accountUid, tx.hash);

            if (transactionExists(sql, ethTxUid)) {
                // UPDATE (we only update block information)
                if (tx.block.nonEmpty()) {
                    sql << "UPDATE ethereum_transactions SET block_uid = :uid WHERE hash = :tx_hash",
                            use(blockUid), use(tx.hash);
                }
                return ethTxUid;
            } else {
                // Insert
                if (tx.block.nonEmpty()) {
                    BlockDatabaseHelper::putBlock(sql, tx.block.getValue());
                }

                auto txInputData = hex::toString(tx.inputData);
                sql << "INSERT INTO ethereum_transactions VALUES(:tx_uid, :hash, :nonce, :value, :block_uid, :time, :sender, :receiver, :input_data, :gasPrice, :gasLimit, :gasUsed, :confirmations, :status)",
                        use(ethTxUid),
                        use(tx.hash),
                        use(tx.nonce),
                        use(tx.value.toHexString()),
                        use(blockUid),
                        use(tx.receivedAt),
                        use(tx.sender),
                        use(tx.receiver),
                        use(txInputData),
                        use(tx.gasPrice.toHexString()),
                        use(tx.gasLimit.toHexString()),
                        use(tx.gasUsed.getValueOr(BigInt::ZERO).toHexString()),
                        use(tx.confirmations),
                        use(tx.status);

                return ethTxUid;
            }
        }
    }
}
<commit_msg>Fix ETH transaction details in ETH operations<commit_after>/*
 *
 * EthereumLikeTransactionDatabaseHelper
 *
 * Created by El Khalil Bellakrid on 14/07/2018.
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 Ledger
 *
 * 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.
 *
 */

#include "EthereumLikeTransactionDatabaseHelper.h"
#include <math/BigInt.h>
#include <utils/hex.h>
#include <database/soci-option.h>
#include <database/soci-date.h>
#include <database/soci-number.h>
#include <crypto/SHA256.hpp>
#include <wallet/common/database/BlockDatabaseHelper.h>

using namespace soci;

namespace ledger {
    namespace core {

        bool EthereumLikeTransactionDatabaseHelper::getTransactionByHash(soci::session &sql,
                                                                         const std::string &hash,
                                                                         EthereumLikeBlockchainExplorerTransaction &tx) {

            rowset<row> rows = (sql.prepare << "SELECT  tx.hash, tx.value, tx.nonce, tx.time, tx.input_data, tx.gas_price, "
                                                "tx.gas_limit, tx.gas_used, tx.sender, tx.receiver, tx.confirmations, tx.status, "
                                                "block.hash, block.height, block.time, block.currency_name "
                                                "FROM ethereum_transactions AS tx "
                                                "LEFT JOIN blocks AS block ON tx.block_uid = block.uid "
                                                "WHERE tx.hash = :hash", use(hash));

            for (auto& row : rows) {
                inflateTransaction(sql, row, tx);
                return true;
            }

            return false;
        }

        bool EthereumLikeTransactionDatabaseHelper::inflateTransaction(soci::session &sql,
                                                                       const soci::row &row,
                                                                       EthereumLikeBlockchainExplorerTransaction &tx) {
            tx.hash = row.get<std::string>(0);
            tx.value = BigInt::fromHex(row.get<std::string>(1));
            auto nonceBytes = hex::toByteArray(row.get<std::string>(2));
            auto shift = 0;
            for (auto& byte : nonceBytes) {
                tx.nonce += byte << shift;
                shift += 8;
            }

            tx.receivedAt = row.get<std::chrono::system_clock::time_point>(3);
            tx.inputData = hex::toByteArray(row.get<std::string>(4));

            tx.gasPrice = BigInt::fromHex(row.get<std::string>(5));
            tx.gasLimit = BigInt::fromHex(row.get<std::string>(6));
            tx.gasUsed = BigInt::fromHex(row.get<std::string>(7));

            tx.sender = row.get<std::string>(8);
            tx.receiver = row.get<std::string>(9);

            tx.confirmations = get_number<uint64_t>(row, 10);
            tx.status = get_number<uint64_t>(row, 11);
            if (row.get_indicator(12) != i_null) {
                EthereumLikeBlockchainExplorer::Block block;
                block.hash = row.get<std::string>(12);
                block.height = get_number<uint64_t>(row, 13);
                block.time = row.get<std::chrono::system_clock::time_point>(14);
                block.currencyName = row.get<std::string>(15);
                tx.block = block;
            }

            return true;
        }

        bool EthereumLikeTransactionDatabaseHelper::transactionExists(soci::session &sql,
                                                                      const std::string &ethTxUid) {
            int32_t count = 0;
            sql << "SELECT COUNT(*) FROM ethereum_transactions WHERE transaction_uid = :ethTxUid", use(ethTxUid), into(count);
            return count == 1;
        }

        std::string EthereumLikeTransactionDatabaseHelper::createEthereumTransactionUid(const std::string& accountUid,
                                                                                const std::string& txHash) {
            auto result = SHA256::stringToHexHash(fmt::format("uid:{}+{}", accountUid, txHash));
            return result;
        }

        std::string EthereumLikeTransactionDatabaseHelper::putTransaction(soci::session &sql,
                                                                         const std::string& accountUid,
                                                                         const EthereumLikeBlockchainExplorerTransaction &tx) {
            auto blockUid = tx.block.map<std::string>([] (const EthereumLikeBlockchainExplorer::Block& block) {
                return block.getUid();
            });

            auto ethTxUid = createEthereumTransactionUid(accountUid, tx.hash);

            if (transactionExists(sql, ethTxUid)) {
                // UPDATE (we only update block information)
                if (tx.block.nonEmpty()) {
                    sql << "UPDATE ethereum_transactions SET block_uid = :uid WHERE hash = :tx_hash",
                            use(blockUid), use(tx.hash);
                }
                return ethTxUid;
            } else {
                // Insert
                if (tx.block.nonEmpty()) {
                    BlockDatabaseHelper::putBlock(sql, tx.block.getValue());
                }

                auto txInputData = hex::toString(tx.inputData);
                sql << "INSERT INTO ethereum_transactions VALUES(:tx_uid, :hash, :nonce, :value, :block_uid, :time, :sender, :receiver, :input_data, :gasPrice, :gasLimit, :gasUsed, :confirmations, :status)",
                        use(ethTxUid),
                        use(tx.hash),
                        use(tx.nonce),
                        use(tx.value.toHexString()),
                        use(blockUid),
                        use(tx.receivedAt),
                        use(tx.sender),
                        use(tx.receiver),
                        use(txInputData),
                        use(tx.gasPrice.toHexString()),
                        use(tx.gasLimit.toHexString()),
                        use(tx.gasUsed.getValueOr(BigInt::ZERO).toHexString()),
                        use(tx.confirmations),
                        use(tx.status);

                return ethTxUid;
            }
        }
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef SMP_HH_
#define SMP_HH_

#include "reactor.hh"
#include "future-util.hh"

template <typename Service>
class distributed {
    std::vector<Service*> _instances;
public:
    distributed() {}
    distributed(const distributed& other) = delete;
    distributed(distributed&& other) = default;
    distributed& operator=(const distributed& other) = delete;
    distributed& operator=(distributed& other) = default;
    ~distributed();

    // Start @Service by constructing an instance on every engine
    // with @args passed to the constructor.
    // The return value becomes ready when all instances have been
    // constructed.
    template <typename... Args>
    future<> start(Args&&... args);

    // Stop @Service by destroying the instances started by start().
    // The return value becomes ready when all instances have been
    // destroyed.
    future<> stop();

    // Invoke a method on all instances of @Service.
    // The return value becomes ready when all instances have processed
    // the message.
    template <typename... Args>
    future<> invoke_on_all(future<> (Service::*func)(Args...), Args... args);

    // Invoke a method on all instances of @Service and reduce the results using
    // @Reducer. See ::map_reduce().
    template <typename Reducer, typename Ret, typename... FuncArgs, typename... Args>
    inline
    auto
    map_reduce(Reducer&& r, Ret (Service::*func)(FuncArgs...), Args&&... args)
        -> typename reducer_traits<Reducer>::future_type
    {
        unsigned c = 0;
        return ::map_reduce(_instances.begin(), _instances.end(),
            [&c, func, args = std::make_tuple(std::forward<Args>(args)...)] (Service* inst) mutable {
                return smp::submit_to(c++, [inst, func, args = std::move(args)] () mutable {
                    return apply([inst, func] (Args&&... args) mutable {
                        return (inst->*func)(std::forward<Args>(args)...);
                    }, std::move(args));
                });
            }, std::forward<Reducer>(r));
    }

    // Invoke a method on a specific instance of @Service.
    // The return value (which must be a future) contains the future
    // returned by @Service.
    template <typename Ret, typename... FuncArgs, typename... Args>
    std::enable_if_t<is_future<Ret>::value, Ret>
    invoke_on(unsigned id, Ret (Service::*func)(FuncArgs...), Args&&... args) {
        return smp::submit_to(id, [inst = _instances[id], func, args = std::make_tuple(std::forward<Args>(args)...)] () mutable {
            return apply([inst, func] (Args&&... args) mutable {
                return (inst->*func)(std::forward<Args>(args)...);
            }, std::move(args));
        });
    }

    // Invoke a method on a specific instance of @Service.
    template <typename Ret, typename... FuncArgs, typename... Args>
    std::enable_if_t<!is_future<Ret>::value && !std::is_same<Ret, void>::value, future<Ret>>
    invoke_on(unsigned id, Ret (Service::*func)(FuncArgs...), Args&&... args) {
        return smp::submit_to(id, [inst = _instances[id], func, args = std::make_tuple(std::forward<Args>(args)...)] () mutable {
                return apply([inst, func] (Args&&... args) mutable {
                    return make_ready_future<Ret>((inst->*func)(std::forward<Args>(args)...));
                }, std::move(args));
            });
    }
};

template <typename Service>
distributed<Service>::~distributed() {
	assert(_instances.empty());
}

template <typename Service>
template <typename... Args>
future<>
distributed<Service>::start(Args&&... args) {
    _instances.resize(smp::count);
    unsigned c = 0;
    return parallel_for_each(_instances.begin(), _instances.end(),
        [this, &c, args = std::make_tuple(std::forward<Args>(args)...)] (Service*& inst) mutable {
            return smp::submit_to(c++, [&inst, args = std::move(args)] () mutable {
                inst = apply([] (Args&&... args) {
                    return new Service(std::forward<Args>(args)...);
                }, std::move(args));
            });
    });
}

template <typename Service>
future<>
distributed<Service>::stop() {
    unsigned c = 0;
    return parallel_for_each(_instances.begin(), _instances.end(), [&c] (Service*& inst) mutable {
        return smp::submit_to(c++, [inst] () mutable {
            return inst->stop().then([&inst] () mutable {
                delete inst;
                inst = nullptr;
            });
        });
    }).then([this] {
        _instances.clear();
    });
}

template <typename Service>
template <typename... Args>
inline
future<>
distributed<Service>::invoke_on_all(future<> (Service::*func)(Args...), Args... args) {
    unsigned c = 0;
    return parallel_for_each(_instances.begin(), _instances.end(), [&c, func, args...] (Service* inst) {
        return smp::submit_to(c++, [inst, func, args...] {
            return (inst->*func)(args...);
        });
    });
}

}

#endif /* SMP_HH_ */
<commit_msg>smp: introduce distributed::local()<commit_after>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef SMP_HH_
#define SMP_HH_

#include "reactor.hh"
#include "future-util.hh"

template <typename Service>
class distributed {
    std::vector<Service*> _instances;
public:
    distributed() {}
    distributed(const distributed& other) = delete;
    distributed(distributed&& other) = default;
    distributed& operator=(const distributed& other) = delete;
    distributed& operator=(distributed& other) = default;
    ~distributed();

    // Start @Service by constructing an instance on every engine
    // with @args passed to the constructor.
    // The return value becomes ready when all instances have been
    // constructed.
    template <typename... Args>
    future<> start(Args&&... args);

    // Stop @Service by destroying the instances started by start().
    // The return value becomes ready when all instances have been
    // destroyed.
    future<> stop();

    // Invoke a method on all instances of @Service.
    // The return value becomes ready when all instances have processed
    // the message.
    template <typename... Args>
    future<> invoke_on_all(future<> (Service::*func)(Args...), Args... args);

    // Invoke a method on all instances of @Service and reduce the results using
    // @Reducer. See ::map_reduce().
    template <typename Reducer, typename Ret, typename... FuncArgs, typename... Args>
    inline
    auto
    map_reduce(Reducer&& r, Ret (Service::*func)(FuncArgs...), Args&&... args)
        -> typename reducer_traits<Reducer>::future_type
    {
        unsigned c = 0;
        return ::map_reduce(_instances.begin(), _instances.end(),
            [&c, func, args = std::make_tuple(std::forward<Args>(args)...)] (Service* inst) mutable {
                return smp::submit_to(c++, [inst, func, args = std::move(args)] () mutable {
                    return apply([inst, func] (Args&&... args) mutable {
                        return (inst->*func)(std::forward<Args>(args)...);
                    }, std::move(args));
                });
            }, std::forward<Reducer>(r));
    }

    // Invoke a method on a specific instance of @Service.
    // The return value (which must be a future) contains the future
    // returned by @Service.
    template <typename Ret, typename... FuncArgs, typename... Args>
    std::enable_if_t<is_future<Ret>::value, Ret>
    invoke_on(unsigned id, Ret (Service::*func)(FuncArgs...), Args&&... args) {
        return smp::submit_to(id, [inst = _instances[id], func, args = std::make_tuple(std::forward<Args>(args)...)] () mutable {
            return apply([inst, func] (Args&&... args) mutable {
                return (inst->*func)(std::forward<Args>(args)...);
            }, std::move(args));
        });
    }

    // Invoke a method on a specific instance of @Service.
    template <typename Ret, typename... FuncArgs, typename... Args>
    std::enable_if_t<!is_future<Ret>::value && !std::is_same<Ret, void>::value, future<Ret>>
    invoke_on(unsigned id, Ret (Service::*func)(FuncArgs...), Args&&... args) {
        return smp::submit_to(id, [inst = _instances[id], func, args = std::make_tuple(std::forward<Args>(args)...)] () mutable {
                return apply([inst, func] (Args&&... args) mutable {
                    return make_ready_future<Ret>((inst->*func)(std::forward<Args>(args)...));
                }, std::move(args));
            });
    }

    // Returns reference to the local instance.
    Service& local();
};

template <typename Service>
distributed<Service>::~distributed() {
	assert(_instances.empty());
}

template <typename Service>
template <typename... Args>
future<>
distributed<Service>::start(Args&&... args) {
    _instances.resize(smp::count);
    unsigned c = 0;
    return parallel_for_each(_instances.begin(), _instances.end(),
        [this, &c, args = std::make_tuple(std::forward<Args>(args)...)] (Service*& inst) mutable {
            return smp::submit_to(c++, [&inst, args = std::move(args)] () mutable {
                inst = apply([] (Args&&... args) {
                    return new Service(std::forward<Args>(args)...);
                }, std::move(args));
            });
    });
}

template <typename Service>
future<>
distributed<Service>::stop() {
    unsigned c = 0;
    return parallel_for_each(_instances.begin(), _instances.end(), [&c] (Service*& inst) mutable {
        return smp::submit_to(c++, [inst] () mutable {
            return inst->stop().then([&inst] () mutable {
                delete inst;
                inst = nullptr;
            });
        });
    }).then([this] {
        _instances.clear();
    });
}

template <typename Service>
template <typename... Args>
inline
future<>
distributed<Service>::invoke_on_all(future<> (Service::*func)(Args...), Args... args) {
    unsigned c = 0;
    return parallel_for_each(_instances.begin(), _instances.end(), [&c, func, args...] (Service* inst) {
        return smp::submit_to(c++, [inst, func, args...] {
            return (inst->*func)(args...);
        });
    });
}

template <typename Service>
Service& distributed<Service>::local() {
    return *_instances[engine.cpu_id()];
}

#endif /* SMP_HH_ */
<|endoftext|>


<commit_before>/* logWidget.cc                         KPilot
**
** Copyright (C) 2001 by Dan Pilone
**
** This file defines the log window widget, which logs
** sync-messages during a HotSync.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
** MA 02139, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org.
*/
static const char *logw_id =
	"$Id$";

#include "options.h"

#include <qfile.h>
#include <qlayout.h>
#include <qtextview.h>
#include <qtooltip.h>
#include <qdatetime.h>
#include <qlabel.h>
#include <qpixmap.h>
#include <qtimer.h>
#include <qpushbutton.h>
#include <qhbox.h>
#include <qtextstream.h>
#include <qpainter.h>

#include <kglobal.h>
#include <kstddirs.h>
#include <kprogress.h>
#include <kfiledialog.h>
#include <kmessagebox.h>

#include "logWidget.moc"

LogWidget::LogWidget(QWidget * parent) :
	PilotComponent(parent, "component_log", QString::null),
	DCOPObject("KPilotIface"),
	fLog(0L),
	fShowTime(false),
	fSplash(0L),
	fLabel(0L),
	fProgress(0L)
{
	FUNCTIONSETUP;
	QGridLayout *grid = new QGridLayout(this, 4, 4, SPACING);

	grid->addRowSpacing(0, SPACING);
	grid->addRowSpacing(1, 100);
	grid->addColSpacing(2, 100);
	grid->addRowSpacing(3, SPACING);
	grid->addColSpacing(0, SPACING);
	grid->addColSpacing(3, SPACING);
	grid->setRowStretch(1, 50);
	grid->setColStretch(2, 50);

	fLog = new QTextView(this);
	QToolTip::add(fLog, i18n("<qt>This lists all the messages received "
			"during the current HotSync</qt>"));
	grid->addMultiCellWidget(fLog, 1, 1,1,2);

	fLog->setText(i18n("<qt>HotSync Log</qt>"));

	QHBox *h = new QHBox(this);
	h->setSpacing(SPACING);
	QPushButton *b = new QPushButton(
		i18n("Clear the text of HotSync messages","Clear Log"),
		h);
	QToolTip::add(b,i18n("<qt>Clears the list of messages from the "
		"current HotSync.</qt>"));
	connect(b,SIGNAL(clicked()),this,SLOT(clearLog()));

	b = new QPushButton(i18n("Save Log"),h);
	QToolTip::add(b,i18n("<qt>You can save the list of messages received "
		"during this HotSync to a file (for example for use in a "
		"bug report) by clicking here.</qt>"));
	connect(b,SIGNAL(clicked()),this,SLOT(saveLog()));

	grid->addMultiCellWidget(h,2,2,1,2);

	fLabel = new QLabel(i18n("Sync Progress:"),this);
	grid->addWidget(fLabel,3,1);
	fProgress = new KProgress(this);
	QToolTip::add(fProgress,i18n("<qt>The (estimated) percentage "
		"completed in the current HotSync.</qt>"));
	grid->addWidget(fProgress,3,2);

	QString splashPath =
		KGlobal::dirs()->findResource("data",
			"kpilot/kpilot-splash.png");

	if (!splashPath.isEmpty() && QFile::exists(splashPath))
	{
		fLog->hide();
		fLabel->hide();
		fProgress->hide();

		QPixmap splash(splashPath);
		QPainter painter(&splash);
		painter.setPen(QColor(255, 0, 0));

		int textWidth =fontMetrics().width(KPILOT_VERSION) ;
		int textHeight = fontMetrics().height();

#ifdef DEBUG
		DEBUGKPILOT << fname
			<< ": Using text size "
			<< textWidth << "x" << textHeight
			<< endl;
#endif

		painter.fillRect(splash.width() -  28 - textWidth,
			splash.height() - 6 - textHeight - textHeight ,
			textWidth + 6,
			textHeight + 4,
			black);
		painter.drawText(splash.width() -  25 - textWidth,
			splash.height() - 8 - textHeight,
			KPILOT_VERSION);
		fSplash = new QLabel(this);
		fSplash->setPixmap(splash);
		QTimer::singleShot(3000,this,SLOT(hideSplash()));
		grid->addMultiCellWidget(fSplash,1,3,1,2);
	}

	(void) logw_id;
}

void LogWidget::addMessage(const QString & s)
{
	FUNCTIONSETUP;

	if (fShowTime)
	{
		QString t;

		t = QTime::currentTime().toString();
		t.append("  ");
		t.append(s);
		fLog->append(t);
	}
	else
	{
		fLog->append(s);
	}
}

void LogWidget::addError(const QString & s)
{
	FUNCTIONSETUP;

	QString t("<qt>");

	if (fShowTime)
	{

		t = QTime::currentTime().toString();
		t.append("  ");
	}

	t.append(s);
	t.append("</qt>");

	fLog->append(s);
}

void LogWidget::addProgress(const QString &s,int i)
{
	FUNCTIONSETUP;

	logMessage(s);

	if ((i >= 0) && (i <= 100))
	{
		fProgress->setProgress(i);
	}
}

void LogWidget::syncDone()
{
	FUNCTIONSETUP;

	addMessage(i18n("HotSync Finished!"));
}

void LogWidget::initialize()
{
	FUNCTIONSETUP;
}

void LogWidget::hideSplash()
{
	FUNCTIONSETUP;

	if (fSplash)
	{
		fSplash->hide();
		KPILOT_DELETE(fSplash);
	}

	fLog->show();
	fLabel->show();
	fProgress->show();
}

/* DCOP */ ASYNC LogWidget::logMessage(QString s)
{
	FUNCTIONSETUP;

	if (fLog)
	{
		QTime t = QTime::currentTime();
		QString s1 = t.toString();

		s1.append("  ");
		s1.append(s);
		fLog->append(s1);
	}
}

/* DCOP */ ASYNC LogWidget::logProgress(QString s, int i)
{
	FUNCTIONSETUP;

	addProgress(s,i);
}

/* slot */ void LogWidget::clearLog()
{
	FUNCTIONSETUP;

	if (fLog)
	{
		fLog->setText(QString::null);
	}
}

/* slot */ void LogWidget::saveLog()
{
	FUNCTIONSETUP;

	bool finished = false;

	while (!finished)
	{
		QString saveFileName = KFileDialog::getSaveFileName(
			QString::null,     /* default */
			"*.log",           /* show log files by default */
			this,
			i18n("Save Log"));

		if (saveFileName.isEmpty()) return;
		if (QFile::exists(saveFileName))
		{
			int r = KMessageBox::warningYesNoCancel(
				this,
				i18n("The file exists. Do you want to "
					"overwrite it?"),
				i18n("File Exists"));
			if (r==KMessageBox::Yes)
			{
				finished=saveFile(saveFileName);
			}

			if (r==KMessageBox::Cancel) return;
		}
		else
		{
			finished=saveFile(saveFileName);
		}
	}
}

bool LogWidget::saveFile(const QString &saveFileName)
{
	FUNCTIONSETUP;

	QFile f(saveFileName);
	if (!f.open(IO_WriteOnly))
	{
		int r = KMessageBox::questionYesNo(this,
			i18n("<qt>Can't open the file "%1" "
				"for writing. Try again?</qt>"),
			i18n("Can't Save"));

		if (r==KMessageBox::Yes) return false;
		return true;
	}
	else
	{
		QTextStream t(&f);
		t << fLog->text();
	}

	f.close();
}

// $Log$
// Revision 1.11  2001/12/31 14:41:06  harald
// Make it compile
//
// Revision 1.10  2001/12/31 09:38:09  adridg
// Splash patch by Aaron
//
// Revision 1.9  2001/12/29 15:44:16  adridg
// Missing progress slots
//
// Revision 1.8  2001/11/25 22:02:57  adridg
// Save/clear the sync log
//
// Revision 1.7  2001/11/18 16:59:55  adridg
// New icons, DCOP changes
//
<commit_msg>Fix build with current kdelibs<commit_after>/* logWidget.cc                         KPilot
**
** Copyright (C) 2001 by Dan Pilone
**
** This file defines the log window widget, which logs
** sync-messages during a HotSync.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
** MA 02139, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org.
*/
static const char *logw_id =
	"$Id$";

#include "options.h"

#include <qfile.h>
#include <qlayout.h>
#include <qtextview.h>
#include <qtooltip.h>
#include <qdatetime.h>
#include <qlabel.h>
#include <qpixmap.h>
#include <qtimer.h>
#include <qpushbutton.h>
#include <qhbox.h>
#include <qtextstream.h>
#include <qpainter.h>

#include <kglobal.h>
#include <kstddirs.h>
#include <kprogress.h>
#include <kfiledialog.h>
#include <kmessagebox.h>

#include "logWidget.moc"

LogWidget::LogWidget(QWidget * parent) :
	PilotComponent(parent, "component_log", QString::null),
	DCOPObject("KPilotIface"),
	fLog(0L),
	fShowTime(false),
	fSplash(0L),
	fLabel(0L),
	fProgress(0L)
{
	FUNCTIONSETUP;
	QGridLayout *grid = new QGridLayout(this, 4, 4, SPACING);

	grid->addRowSpacing(0, SPACING);
	grid->addRowSpacing(1, 100);
	grid->addColSpacing(2, 100);
	grid->addRowSpacing(3, SPACING);
	grid->addColSpacing(0, SPACING);
	grid->addColSpacing(3, SPACING);
	grid->setRowStretch(1, 50);
	grid->setColStretch(2, 50);

	fLog = new QTextView(this);
	QToolTip::add(fLog, i18n("<qt>This lists all the messages received "
			"during the current HotSync</qt>"));
	grid->addMultiCellWidget(fLog, 1, 1,1,2);

	fLog->setText(i18n("<qt>HotSync Log</qt>"));

	QHBox *h = new QHBox(this);
	h->setSpacing(SPACING);
	QPushButton *b = new QPushButton(
		i18n("Clear the text of HotSync messages","Clear Log"),
		h);
	QToolTip::add(b,i18n("<qt>Clears the list of messages from the "
		"current HotSync.</qt>"));
	connect(b,SIGNAL(clicked()),this,SLOT(clearLog()));

	b = new QPushButton(i18n("Save Log"),h);
	QToolTip::add(b,i18n("<qt>You can save the list of messages received "
		"during this HotSync to a file (for example for use in a "
		"bug report) by clicking here.</qt>"));
	connect(b,SIGNAL(clicked()),this,SLOT(saveLog()));

	grid->addMultiCellWidget(h,2,2,1,2);

	fLabel = new QLabel(i18n("Sync Progress:"),this);
	grid->addWidget(fLabel,3,1);
	fProgress = new KProgress(this);
	QToolTip::add(fProgress,i18n("<qt>The (estimated) percentage "
		"completed in the current HotSync.</qt>"));
	grid->addWidget(fProgress,3,2);

	QString splashPath =
		KGlobal::dirs()->findResource("data",
			"kpilot/kpilot-splash.png");

	if (!splashPath.isEmpty() && QFile::exists(splashPath))
	{
		fLog->hide();
		fLabel->hide();
		fProgress->hide();

		QPixmap splash(splashPath);
		QPainter painter(&splash);
		painter.setPen(QColor(255, 0, 0));

		int textWidth =fontMetrics().width(KPILOT_VERSION) ;
		int textHeight = fontMetrics().height();

#ifdef DEBUG
		DEBUGKPILOT << fname
			<< ": Using text size "
			<< textWidth << "x" << textHeight
			<< endl;
#endif

		painter.fillRect(splash.width() -  28 - textWidth,
			splash.height() - 6 - textHeight - textHeight ,
			textWidth + 6,
			textHeight + 4,
			black);
		painter.drawText(splash.width() -  25 - textWidth,
			splash.height() - 8 - textHeight,
			KPILOT_VERSION);
		fSplash = new QLabel(this);
		fSplash->setPixmap(splash);
		QTimer::singleShot(3000,this,SLOT(hideSplash()));
		grid->addMultiCellWidget(fSplash,1,3,1,2);
	}

	(void) logw_id;
}

void LogWidget::addMessage(const QString & s)
{
	FUNCTIONSETUP;

	if (fShowTime)
	{
		QString t;

		t = QTime::currentTime().toString();
		t.append("  ");
		t.append(s);
		fLog->append(t);
	}
	else
	{
		fLog->append(s);
	}
}

void LogWidget::addError(const QString & s)
{
	FUNCTIONSETUP;

	QString t("<qt>");

	if (fShowTime)
	{

		t = QTime::currentTime().toString();
		t.append("  ");
	}

	t.append(s);
	t.append("</qt>");

	fLog->append(s);
}

void LogWidget::addProgress(const QString &s,int i)
{
	FUNCTIONSETUP;

	logMessage(s);

	if ((i >= 0) && (i <= 100))
	{
		fProgress->setValue(i);
	}
}

void LogWidget::syncDone()
{
	FUNCTIONSETUP;

	addMessage(i18n("HotSync Finished!"));
}

void LogWidget::initialize()
{
	FUNCTIONSETUP;
}

void LogWidget::hideSplash()
{
	FUNCTIONSETUP;

	if (fSplash)
	{
		fSplash->hide();
		KPILOT_DELETE(fSplash);
	}

	fLog->show();
	fLabel->show();
	fProgress->show();
}

/* DCOP */ ASYNC LogWidget::logMessage(QString s)
{
	FUNCTIONSETUP;

	if (fLog)
	{
		QTime t = QTime::currentTime();
		QString s1 = t.toString();

		s1.append("  ");
		s1.append(s);
		fLog->append(s1);
	}
}

/* DCOP */ ASYNC LogWidget::logProgress(QString s, int i)
{
	FUNCTIONSETUP;

	addProgress(s,i);
}

/* slot */ void LogWidget::clearLog()
{
	FUNCTIONSETUP;

	if (fLog)
	{
		fLog->setText(QString::null);
	}
}

/* slot */ void LogWidget::saveLog()
{
	FUNCTIONSETUP;

	bool finished = false;

	while (!finished)
	{
		QString saveFileName = KFileDialog::getSaveFileName(
			QString::null,     /* default */
			"*.log",           /* show log files by default */
			this,
			i18n("Save Log"));

		if (saveFileName.isEmpty()) return;
		if (QFile::exists(saveFileName))
		{
			int r = KMessageBox::warningYesNoCancel(
				this,
				i18n("The file exists. Do you want to "
					"overwrite it?"),
				i18n("File Exists"));
			if (r==KMessageBox::Yes)
			{
				finished=saveFile(saveFileName);
			}

			if (r==KMessageBox::Cancel) return;
		}
		else
		{
			finished=saveFile(saveFileName);
		}
	}
}

bool LogWidget::saveFile(const QString &saveFileName)
{
	FUNCTIONSETUP;

	QFile f(saveFileName);
	if (!f.open(IO_WriteOnly))
	{
		int r = KMessageBox::questionYesNo(this,
			i18n("<qt>Can't open the file "%1" "
				"for writing. Try again?</qt>"),
			i18n("Can't Save"));

		if (r==KMessageBox::Yes) return false;
		return true;
	}
	else
	{
		QTextStream t(&f);
		t << fLog->text();
	}

	f.close();
}

// $Log$
// Revision 1.12  2002/01/21 23:58:55  aseigo
// KProgress updates
//
// Revision 1.11  2001/12/31 14:41:06  harald
// Make it compile
//
// Revision 1.10  2001/12/31 09:38:09  adridg
// Splash patch by Aaron
//
// Revision 1.9  2001/12/29 15:44:16  adridg
// Missing progress slots
//
// Revision 1.8  2001/11/25 22:02:57  adridg
// Save/clear the sync log
//
// Revision 1.7  2001/11/18 16:59:55  adridg
// New icons, DCOP changes
//
<|endoftext|>


<commit_before>/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

#include <ns3/core-module.h>
#include <ns3/node.h>
#include <ns3/point-to-point-net-device.h>
#include <ns3/point-to-point-channel.h>
#include <ns3/drop-tail-queue.h>

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("simulation");

int
main (int argc, char *argv[])
{
  Time::SetResolution (Time::MS);

  // Parametros de la simulacion

  uint32_t nVoip = 2;
  uint32_t nHttpClient = 3;

  // Preparar los parametros

  cmd.AddValue ("Voip", "Número de nodos VoIP", nVoip);
  cmd.AddValue ("HttpClient", "Número de nodos cliente HTTP", nHttpClient);
  cmd.Parse (argc,argv);

  /*********************
  * Creacion escenario *
  **********************/

  // Nodos VoIP y Http
  NodeContainer VoipNodes;
  VoipNodes.create(nVoip);
  NodeContainer HttpClientNodes;
  HttpClientNodes.create(nHttpClient);

  // Nodos que pertenecen al enlace punto a punto
  NodeContainer p2pNodes;
  p2pNodes.Create (2);

  // Nodos que pertenecen al enlace csma
  NodeContainer csmaNodes;
  csmaNodes.Add (p2pNodes.Get (1));
  csmaNodes.Add (VoipNodes);
  csmaNodes.Add (HttpClientNodes);

  // Instalamos el dispositivo en los nodos punto a punto
  PointToPointHelper pointToPoint;
  NetDeviceContainer p2pDevices;
  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("2Mbps"));
  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
  p2pDevices = pointToPoint.Install (p2pNodes);

  // Instalamos el dispositivo de red en los nodos csma
  CsmaHelper csma;
  NetDeviceContainer csmaDevices;
  csma.SetChannelAttribute ("DataRate", StringValue("100Mbps"));
  csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
  csmaDevices = csma.Install (csmaNodes);

  // Instalamos la pila TCP/IP en todos los nodos
  InternetStackHelper stack;
  stack.Install (p2pNodes.Get (0));
  stack.Install (csmaNodes);

  // Asignamos direcciones a cada una de las interfaces
  // Utilizamos dos rangos de direcciones diferentes:
  //    - un rango para los dos nodos del enlace
  //      punto a punto
  //    - un rango para los nodos de la red de área local.
  Ipv4AddressHelper address;
  Ipv4InterfaceContainer p2pInterfaces;
  address.SetBase ("10.1.1.0", "255.255.255.0");
  p2pInterfaces = address.Assign (p2pDevices);
  Ipv4InterfaceContainer csmaInterfaces;
  address.SetBase ("10.1.2.0", "255.255.255.0");
  csmaInterfaces = address.Assign (csmaDevices);

  // Calculamos las rutas del escenario. Con este comando, los
  //     nodos de la red de área local definen que para acceder
  //     al nodo del otro extremo del enlace punto a punto deben
  //     utilizar el primer nodo como ruta por defecto.
  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

  /*******************************
   * Instalacion de aplicaciones *
   *******************************/

  // Instalacion de aplicacion VoIP
  uint16_t port = 9;
  PacketSinkHelper sink ("ns3::UdpSocketFactory", Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
  ApplicationContainer app = sink.Install (p2pNodes.Get (0));

  G711Generator VoIPapp;
  VoIPapp.SetRemote("ns3::UdpSocketFactory",serverAddress);
  for(uint32_t i = 0 ; i < nVoip ; i++)
    nodes.Get(i)->AddApplication(&VoIPapp);

  VoIPapp.Start (Seconds (1.0));
  VoIPapp.Stop (Seconds (10.0));

  // Instalacion de aplicacion HttpGenerator

  //*********************************************************************************************************************

  // Dos dispositivos de red
  Ptr<PointToPointNetDevice> dispTx = CreateObject<PointToPointNetDevice> ();
  Ptr<PointToPointNetDevice> dispRx = CreateObject<PointToPointNetDevice> ();
  // Un canal punto a punto
  Ptr<PointToPointChannel> canal = CreateObject<PointToPointChannel> ();;
  // Una aplicación transmisora
  BitAlternanteTx transmisor(dispRx, Time("10ms"), 2048);
  // Y una receptora
  BitAlternanteRx receptor(dispTx);

  // Montamos el escenario:
  // Añadimos una cola a cada dispositivo
  dispTx->SetQueue (CreateObject<DropTailQueue> ());
  dispRx->SetQueue (CreateObject<DropTailQueue> ());
  // Añadimos cada dispositivo a su nodo
  nodoTx->AddDevice (dispTx);
  nodoRx->AddDevice (dispRx);
  // Añadimos cada aplicación a su nodo
  nodoTx->AddApplication(&transmisor);
  nodoRx->AddApplication(&receptor);
  // Asociamos los dos dispositivos al canal
  dispTx->Attach (canal);
  dispRx->Attach (canal);

  // Modificamos los parámetos configurables
  canal->SetAttribute ("Delay", StringValue ("2ms"));
  dispTx->SetAttribute ("DataRate", StringValue ("5Mbps"));

  // Activamos el transmisor
  transmisor.SetStartTime (Seconds (1.0));
  transmisor.SetStopTime (Seconds (10.0));

  NS_LOG_UNCOND ("Voy a simular");
  Simulator::Run ();
  Simulator::Destroy ();

  NS_LOG_UNCOND ("Total paquetes: " << transmisor.TotalDatos());

  return 0;
}
<commit_msg>Instalacion Voip mejorada<commit_after>/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

#include <ns3/core-module.h>
#include <ns3/node.h>
#include <ns3/point-to-point-net-device.h>
#include <ns3/point-to-point-channel.h>
#include <ns3/drop-tail-queue.h>

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("simulation");

int
main (int argc, char *argv[])
{
  Time::SetResolution (Time::MS);

  // Parametros de la simulacion

  uint32_t nVoip = 2;
  uint32_t nHttpClient = 3;

  // Preparar los parametros

  cmd.AddValue ("Voip", "Número de nodos VoIP", nVoip);
  cmd.AddValue ("HttpClient", "Número de nodos cliente HTTP", nHttpClient);
  cmd.Parse (argc,argv);

  /*********************
  * Creacion escenario *
  **********************/

  // Nodos VoIP y Http
  NodeContainer VoipNodes;
  VoipNodes.create(nVoip);
  NodeContainer HttpClientNodes;
  HttpClientNodes.create(nHttpClient);

  // Nodos que pertenecen al enlace punto a punto
  NodeContainer p2pNodes;
  p2pNodes.Create (2);

  // Nodos que pertenecen al enlace csma
  NodeContainer csmaNodes;
  csmaNodes.Add (p2pNodes.Get (1));
  csmaNodes.Add (VoipNodes);
  csmaNodes.Add (HttpClientNodes);

  // Instalamos el dispositivo en los nodos punto a punto
  PointToPointHelper pointToPoint;
  NetDeviceContainer p2pDevices;
  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("2Mbps"));
  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
  p2pDevices = pointToPoint.Install (p2pNodes);

  // Instalamos el dispositivo de red en los nodos csma
  CsmaHelper csma;
  NetDeviceContainer csmaDevices;
  csma.SetChannelAttribute ("DataRate", StringValue("100Mbps"));
  csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
  csmaDevices = csma.Install (csmaNodes);

  // Instalamos la pila TCP/IP en todos los nodos
  InternetStackHelper stack;
  stack.Install (p2pNodes.Get (0));
  stack.Install (csmaNodes);

  // Asignamos direcciones a cada una de las interfaces
  // Utilizamos dos rangos de direcciones diferentes:
  //    - un rango para los dos nodos del enlace
  //      punto a punto
  //    - un rango para los nodos de la red de área local.
  Ipv4AddressHelper address;
  Ipv4InterfaceContainer p2pInterfaces;
  address.SetBase ("10.1.1.0", "255.255.255.0");
  p2pInterfaces = address.Assign (p2pDevices);
  Ipv4InterfaceContainer csmaInterfaces;
  address.SetBase ("10.1.2.0", "255.255.255.0");
  csmaInterfaces = address.Assign (csmaDevices);

  // Calculamos las rutas del escenario. Con este comando, los
  //     nodos de la red de área local definen que para acceder
  //     al nodo del otro extremo del enlace punto a punto deben
  //     utilizar el primer nodo como ruta por defecto.
  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

  /*******************************
   * Instalacion de aplicaciones *
   *******************************/

  // Instalacion de aplicacion VoIP
  uint16_t port = 9;
  PacketSinkHelper sink ("ns3::UdpSocketFactory", Address (InetSocketAddress (p2pInterfaces.GetAddress (0), port))); //sumidero udp en el nodo p2p para todo lo que vaya a su ip y a ese puerto
  ApplicationContainer sinkapp = sink.Install (p2pNodes.Get (0));

  G711Generator VoIPapp;
  VoIPapp.SetRemote("ns3::UdpSocketFactory", p2pInterfaces.GetAddress (0), port); //aplicacion Voip que envia a la ip del nodo p2p y por un puerto.
  for(uint32_t i = 0 ; i < nVoip ; i++)
    VoipNodes.Get(i)->AddApplication(&VoIPapp);

  VoIPapp.Start (Seconds (1.0));
  VoIPapp.Stop (Seconds (10.0));

  // Instalacion de aplicacion HttpGenerator

  NS_LOG_UNCOND ("Voy a simular");
  Simulator::Run ();
  Simulator::Destroy ();

  return 0;
}
<|endoftext|>


<commit_before>/**
 * @file
 *
 * @brief Implementation of entry points
 *
 * @copyright BSD License (see doc/LICENSE.md or http://www.libelektra.org)
 *
 */

#include "type.hpp"

#include "type_checker.hpp"

using namespace ckdb;
#include <kdberrors.h>
#include <kdbplugin.hpp>

typedef Delegator<elektra::TypeChecker> TC;

static void setError (Key * key, Key * errorKey)
{
	std::string msg = "The type ";
	msg += keyString (keyGetMeta (key, "check/type"));
	msg += " failed to match for ";
	const char * name = keyName (key);
	if (name) msg += name;
	msg += " with string: ";
	const char * value = keyString (key);
	if (value) msg += value;
	ELEKTRA_SET_ERROR (52, errorKey, msg.c_str ());
}

extern "C" {

int elektraTypeValidateKey (ckdb::Key * key, ckdb::Key * errorKey)
{
	kdb::KeySet config;
	elektra::TypeChecker tc (config);
	int ret = 1;

	kdb::Key k (key); // reinterpret_cast<kdb::Key &> (key)
	if (!tc.check (k))
	{
		setError (key, errorKey);
		ret = 0;
	}
	k.release ();
	return ret;
}

int elektraTypeOpen (ckdb::Plugin * handle, ckdb::Key * errorKey)
{
	/* plugin initialization logic */
	return TC::open (handle, errorKey);
}

int elektraTypeClose (ckdb::Plugin * handle, ckdb::Key * errorKey)
{
	/* free all plugin resources and shut it down */
	return TC::close (handle, errorKey);
}

int elektraTypeGet (ckdb::Plugin *, ckdb::KeySet * returned, ckdb::Key *)
{
	/* configuration only */
	KeySet * n;
	ksAppend (returned,
		  n = ksNew (30, keyNew ("system/elektra/modules/type", KEY_VALUE, "type plugin waits for your orders", KEY_END),
			     keyNew ("system/elektra/modules/type/exports", KEY_END),
			     keyNew ("system/elektra/modules/type/exports/open", KEY_FUNC, elektraTypeOpen, KEY_END),
			     keyNew ("system/elektra/modules/type/exports/close", KEY_FUNC, elektraTypeClose, KEY_END),
			     keyNew ("system/elektra/modules/type/exports/get", KEY_FUNC, elektraTypeGet, KEY_END),
			     keyNew ("system/elektra/modules/type/exports/set", KEY_FUNC, elektraTypeSet, KEY_END),
			     keyNew ("system/elektra/modules/type/exports/validateKey", KEY_FUNC, elektraTypeValidateKey, KEY_END),
#include "readme_type.c"
			     keyNew ("system/elektra/modules/type/infos/version", KEY_VALUE, PLUGINVERSION, KEY_END), KS_END));
	ksDel (n);

	return 1; /* success */
}

int elektraTypeSet (ckdb::Plugin * handle, ckdb::KeySet * returned, ckdb::Key * parentKey)
{
	/* set all keys */

	if (!TC::get (handle)->check (reinterpret_cast<kdb::KeySet &> (returned)))
	{
		setError (ksCurrent (returned), parentKey);
		return -1;
	}

	return 1; /* success */
}

ckdb::Plugin * ELEKTRA_PLUGIN_EXPORT (type)
{
	// clang-format off
	return elektraPluginExport("type",
		ELEKTRA_PLUGIN_OPEN,	&elektraTypeOpen,
		ELEKTRA_PLUGIN_CLOSE,	&elektraTypeClose,
		ELEKTRA_PLUGIN_GET,	&elektraTypeGet,
		ELEKTRA_PLUGIN_SET,	&elektraTypeSet,
		ELEKTRA_PLUGIN_END);
}

}
<commit_msg>type: avoid KeySet cast<commit_after>/**
 * @file
 *
 * @brief Implementation of entry points
 *
 * @copyright BSD License (see doc/LICENSE.md or http://www.libelektra.org)
 *
 */

#include "type.hpp"

#include "type_checker.hpp"

using namespace ckdb;
#include <kdberrors.h>
#include <kdbplugin.hpp>

typedef Delegator<elektra::TypeChecker> TC;

static void setError (Key * key, Key * errorKey)
{
	std::string msg = "The type ";
	msg += keyString (keyGetMeta (key, "check/type"));
	msg += " failed to match for ";
	const char * name = keyName (key);
	if (name) msg += name;
	msg += " with string: ";
	const char * value = keyString (key);
	if (value) msg += value;
	ELEKTRA_SET_ERROR (52, errorKey, msg.c_str ());
}

extern "C" {

int elektraTypeValidateKey (ckdb::Key * key, ckdb::Key * errorKey)
{
	kdb::KeySet config;
	elektra::TypeChecker tc (config);
	int ret = 1;

	kdb::Key k (key); // reinterpret_cast<kdb::Key &> (key)
	if (!tc.check (k))
	{
		setError (key, errorKey);
		ret = 0;
	}

	k.release ();
	return ret;
}

int elektraTypeOpen (ckdb::Plugin * handle, ckdb::Key * errorKey)
{
	/* plugin initialization logic */
	return TC::open (handle, errorKey);
}

int elektraTypeClose (ckdb::Plugin * handle, ckdb::Key * errorKey)
{
	/* free all plugin resources and shut it down */
	return TC::close (handle, errorKey);
}

int elektraTypeGet (ckdb::Plugin *, ckdb::KeySet * returned, ckdb::Key *)
{
	/* configuration only */
	KeySet * n;
	ksAppend (returned,
		  n = ksNew (30, keyNew ("system/elektra/modules/type", KEY_VALUE, "type plugin waits for your orders", KEY_END),
			     keyNew ("system/elektra/modules/type/exports", KEY_END),
			     keyNew ("system/elektra/modules/type/exports/open", KEY_FUNC, elektraTypeOpen, KEY_END),
			     keyNew ("system/elektra/modules/type/exports/close", KEY_FUNC, elektraTypeClose, KEY_END),
			     keyNew ("system/elektra/modules/type/exports/get", KEY_FUNC, elektraTypeGet, KEY_END),
			     keyNew ("system/elektra/modules/type/exports/set", KEY_FUNC, elektraTypeSet, KEY_END),
			     keyNew ("system/elektra/modules/type/exports/validateKey", KEY_FUNC, elektraTypeValidateKey, KEY_END),
#include "readme_type.c"
			     keyNew ("system/elektra/modules/type/infos/version", KEY_VALUE, PLUGINVERSION, KEY_END), KS_END));
	ksDel (n);

	return 1; /* success */
}

int elektraTypeSet (ckdb::Plugin * handle, ckdb::KeySet * returned, ckdb::Key * parentKey)
{
	int ret = 1;

	kdb::KeySet ks (returned); // reinterpret_cast<kdb::KeySet &> (returned)
	if (!TC::get (handle)->check (ks))
	{
		setError (ksCurrent (returned), parentKey);
		ret = -1;
	}

	ks.release ();
	return ret;
}

ckdb::Plugin * ELEKTRA_PLUGIN_EXPORT (type)
{
	// clang-format off
	return elektraPluginExport("type",
		ELEKTRA_PLUGIN_OPEN,	&elektraTypeOpen,
		ELEKTRA_PLUGIN_CLOSE,	&elektraTypeClose,
		ELEKTRA_PLUGIN_GET,	&elektraTypeGet,
		ELEKTRA_PLUGIN_SET,	&elektraTypeSet,
		ELEKTRA_PLUGIN_END);
}

}
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- *
 *                                   Lepton                                   *
 * -------------------------------------------------------------------------- *
 * This is part of the Lepton expression parser originating from              *
 * Simbios, the NIH National Center for Physics-Based Simulation of           *
 * Biological Structures at Stanford, funded under the NIH Roadmap for        *
 * Medical Research, grant U54 GM072970. See https://simtk.org.               *
 *                                                                            *
 * Portions Copyright (c) 2005-2016 Stanford University and the Authors.      *
 * Authors: Peter Eastman                                                     *
 * Contributors:                                                              *
 *                                                                            *
 * 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, CONTRIBUTORS 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.                                     *
 * -------------------------------------------------------------------------- */

#include "lepton/ExpressionProgram.h"
#include "lepton/Operation.h"
#include "lepton/ParsedExpression.h"

using namespace Lepton;
using namespace std;

ExpressionProgram::ExpressionProgram() : maxArgs(0), stackSize(0) {
}

ExpressionProgram::ExpressionProgram(const ParsedExpression& expression) : maxArgs(0), stackSize(0) {
    buildProgram(expression.getRootNode());
    int currentStackSize = 0;
    for (int i = 0; i < (int) operations.size(); i++) {
        int args = operations[i]->getNumArguments();
        if (args > maxArgs)
            maxArgs = args;
        currentStackSize += 1-args;
        if (currentStackSize > stackSize)
            stackSize = currentStackSize;
    }
}

ExpressionProgram::~ExpressionProgram() {
    for (int i = 0; i < (int) operations.size(); i++)
        delete operations[i];
}

ExpressionProgram::ExpressionProgram(const ExpressionProgram& program) {
    *this = program;
}

ExpressionProgram& ExpressionProgram::operator=(const ExpressionProgram& program) {
    maxArgs = program.maxArgs;
    stackSize = program.stackSize;
    operations.resize(program.operations.size());
    for (int i = 0; i < (int) operations.size(); i++)
        operations[i] = program.operations[i]->clone();
    return *this;
}

void ExpressionProgram::buildProgram(const ExpressionTreeNode& node) {
    for (int i = (int) node.getChildren().size()-1; i >= 0; i--)
        buildProgram(node.getChildren()[i]);
    operations.push_back(node.getOperation().clone());
}

int ExpressionProgram::getNumOperations() const {
    return (int) operations.size();
}

const Operation& ExpressionProgram::getOperation(int index) const {
    return *operations[index];
}

int ExpressionProgram::getStackSize() const {
    return stackSize;
}

double ExpressionProgram::evaluate() const {
    return evaluate(map<string, double>());
}

double ExpressionProgram::evaluate(const std::map<std::string, double>& variables) const {
    vector<double> stack(stackSize+1);
    int stackPointer = stackSize;
    for (int i = 0; i < (int) operations.size(); i++) {
        int numArgs = operations[i]->getNumArguments();
        double result = operations[i]->evaluate(&stack[stackPointer], variables);
        stackPointer += numArgs-1;
        stack[stackPointer] = result;
    }
    return stack[stackSize-1];
}
<commit_msg>Fix memory leak.<commit_after>/* -------------------------------------------------------------------------- *
 *                                   Lepton                                   *
 * -------------------------------------------------------------------------- *
 * This is part of the Lepton expression parser originating from              *
 * Simbios, the NIH National Center for Physics-Based Simulation of           *
 * Biological Structures at Stanford, funded under the NIH Roadmap for        *
 * Medical Research, grant U54 GM072970. See https://simtk.org.               *
 *                                                                            *
 * Portions Copyright (c) 2005-2016 Stanford University and the Authors.      *
 * Authors: Peter Eastman                                                     *
 * Contributors:                                                              *
 *                                                                            *
 * 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, CONTRIBUTORS 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.                                     *
 * -------------------------------------------------------------------------- */

#include "lepton/ExpressionProgram.h"
#include "lepton/Operation.h"
#include "lepton/ParsedExpression.h"

using namespace Lepton;
using namespace std;

ExpressionProgram::ExpressionProgram() : maxArgs(0), stackSize(0) {
}

ExpressionProgram::ExpressionProgram(const ParsedExpression& expression) : maxArgs(0), stackSize(0) {
    buildProgram(expression.getRootNode());
    int currentStackSize = 0;
    for (int i = 0; i < (int) operations.size(); i++) {
        int args = operations[i]->getNumArguments();
        if (args > maxArgs)
            maxArgs = args;
        currentStackSize += 1-args;
        if (currentStackSize > stackSize)
            stackSize = currentStackSize;
    }
}

ExpressionProgram::~ExpressionProgram() {
    for (int i = 0; i < (int) operations.size(); i++)
        delete operations[i];
}

ExpressionProgram::ExpressionProgram(const ExpressionProgram& program) {
    *this = program;
}

ExpressionProgram& ExpressionProgram::operator=(const ExpressionProgram& program) {
    maxArgs = program.maxArgs;
    stackSize = program.stackSize;
    for(auto& op : operations)
        delete op;
    operations.resize(program.operations.size());
    for (int i = 0; i < (int) operations.size(); i++)
        operations[i] = program.operations[i]->clone();
    return *this;
}

void ExpressionProgram::buildProgram(const ExpressionTreeNode& node) {
    for (int i = (int) node.getChildren().size()-1; i >= 0; i--)
        buildProgram(node.getChildren()[i]);
    operations.push_back(node.getOperation().clone());
}

int ExpressionProgram::getNumOperations() const {
    return (int) operations.size();
}

const Operation& ExpressionProgram::getOperation(int index) const {
    return *operations[index];
}

int ExpressionProgram::getStackSize() const {
    return stackSize;
}

double ExpressionProgram::evaluate() const {
    return evaluate(map<string, double>());
}

double ExpressionProgram::evaluate(const std::map<std::string, double>& variables) const {
    vector<double> stack(stackSize+1);
    int stackPointer = stackSize;
    for (int i = 0; i < (int) operations.size(); i++) {
        int numArgs = operations[i]->getNumArguments();
        double result = operations[i]->evaluate(&stack[stackPointer], variables);
        stackPointer += numArgs-1;
        stack[stackPointer] = result;
    }
    return stack[stackSize-1];
}
<|endoftext|>


<commit_before>#define BX_IN_CPU_METHOD 1
#include "bochs.h"
#include <assert.h>

BX_CPU_C *apic_index[APIC_MAX_ID];

bx_apic_c::bx_apic_c(BX_CPU_C *mycpu)
{
  id = APIC_UNKNOWN_ID;
  cpu = mycpu;
  // default address for a local APIC, can be moved
  apic_base_msr = 0xfee00000;
  err_status = 0;
}

bx_apic_c::~bx_apic_c(void)
{
  // nothing for now
}

Bit32u bx_apic_c::get_base (void)
{
  return apic_base_msr;
}

void bx_apic_c::set_id (Bit8u newid) {
  // update apic_index
  if (id != APIC_UNKNOWN_ID) {
    bx_assert (id < APIC_MAX_ID);
    if (apic_index[id] != cpu)
      bx_panic ("inconsistent APIC id table");
    apic_index[id] = NULL;
  }
  id = newid;
  if (apic_index[id] != NULL)
    bx_panic ("duplicate APIC id assigned");
  apic_index[id] = cpu;
  sprintf (cpu->name, "CPU apicid=%02x", (Bit32u)id);
}

void bx_apic_c::set_base (Bit32u newbase)
{
  bx_printf ("relocate APIC to %8x\n", newbase);
  apic_base_msr = newbase;
}

void bx_apic_c::write_handler (Bit32u addr, Bit32u *data, unsigned len)
{
  assert (len == 4);
  bx_printf ("write %08x to APIC address %08x\n", *data, addr);
  //assert (!(addr & 0xf));
  switch (addr & 0xff0) {
  case 0x20: // local APIC id
    id = ((*data)>>24) & 0xf;
    break;
  case 0x30: // local APIC version
    bx_printf ("warning: write to read-only APIC register\n");
    break;
  case 0x80: // task priority
  case 0x90: // arbitration priority
  case 0xa0: // processor priority
  case 0xb0: // EOI
  case 0xd0: // logical destination
  case 0xe0: // destination format
  case 0xf0: // spurious interrupt vector
    break;
  case 0x280: // error status reg
    // Here's what the IA-devguide-3 says on p.7-45:
    // The ESR is a read/write register and is reset after being written to by
    // the processor. A write to the ESR must be done just prior to reading the
    // ESR to allow the register to be updated.
    // This doesn't seem clear.  If the write clears the register, then
    // wouldn't you always read zero?  Otherwise, what does the write do?
    // In my model, the write will do nothing.
    break;
  case 0x300: // interrupt command reg 0-31
    {
      icr_low = *data & ~(1<<12);  // force delivery status bit = 0 (idle)
      // and trigger an interrupt to be sent
      int dest_shorthand = (icr_low >> 18) & 3;
      char *dests[4] = {NULL, "self", "all including self", "all except self" };
      char buf[32];
      unsigned int target_id = (icr_high >> 24);
      sprintf (buf, "APIC 0x%02x\n", target_id);
      bx_printf ("APIC 0x%02x sending interrupt to destination %s",
	 id,
	 (dest_shorthand==0) ? buf : dests[dest_shorthand]);
      bx_printf ("low word of APIC 0x%02x ICR = 0x%04x\n", id, icr_low & 0xffff);
      int delivery_mode = (icr_low >> 8) & 7;
      int vector = (icr_low & 0xff);
      if (delivery_mode == 6 && dest_shorthand == 0) {
	// tell target to start up
	if (target_id > APIC_MAX_ID) bx_panic ("target apic id out of range");
	BX_CPU_C *target = apic_index[target_id];
	if (target == NULL) bx_panic ("apic target id not found");
	target->local_apic.startup_msg (vector);
      } else {
	  bx_printf ("APIC operation not supported");
      }
    }
    break;
  case 0x310: // interrupt command reg 31-63
    icr_high = *data & 0xff000000;
    break;
  case 0x320: // LVT Timer Reg
  case 0x330: // LVT Thermal Monitor
  case 0x340: // LVT Performance Counter
  case 0x350: // LVT LINT0 Reg
  case 0x360: // LVT Lint1 Reg
  case 0x370: // LVT Error Reg
  case 0x380: // initial count for timer
  case 0x390: // current count for timer
  case 0x3e0: // timer divide configuration
  default:
    bx_printf ("APIC register %08x not implemented\n", addr);
  }
}

void bx_apic_c::startup_msg (Bit32u vector)
{
  if (cpu->debug_trap & 0x80000000) {
    cpu->debug_trap &= ~0x80000000;
    cpu->eip = 0;
    cpu->load_seg_reg (&cpu->sregs[BX_SEG_REG_CS], vector*0x100);
    bx_printf ("%s started up at 0x%x by APIC\n", cpu->name, cpu->eip);
  } else {
    bx_printf ("%s started up by APIC, but was not halted at the time\n", cpu->name);
  }
}

void bx_apic_c::read_handler (Bit32u addr, Bit32u *data, unsigned len)
{
  assert (len == 4);
  *data = 0;  // default value for unimplemented registers
  switch (addr & 0xff0) {
  case 0x20: // local APIC id
    *data = (id) << 24;
    break;
  case 0x30: // local APIC version
    *data = 0x00170011;
    break;
  case 0x80: // task priority
  case 0x90: // arbitration priority
  case 0xa0: // processor priority
  case 0xb0: // EOI
  case 0xd0: // logical destination
  case 0xe0: // destination format
  case 0xf0: // spurious interrupt vector
    break;
  case 0x280: // error status reg
    *data = err_status;
    break;
  case 0x300: // interrupt command reg 0-31
    *data = icr_low;
    break;
  case 0x310: // interrupt command reg 31-63
    *data = icr_high;
    break;
  case 0x320: // LVT Timer Reg
  case 0x330: // LVT Thermal Monitor
  case 0x340: // LVT Performance Counter
  case 0x350: // LVT LINT0 Reg
  case 0x360: // LVT Lint1 Reg
  case 0x370: // LVT Error Reg
  case 0x380: // initial count for timer
  case 0x390: // current count for timer
  case 0x3e0: // timer divide configuration
  default:
    bx_printf ("APIC register %08x not implemented\n", addr);
  }
  bx_printf ("read from APIC address %08x = %08x\n", addr, *data);
}

BX_CPU_C
bx_apic_c::*get_cpu (Bit8u id)
{
  bx_assert (id < APIC_MAX_ID);
}
<commit_msg>- now that I need a local APIC and an I/O APIC, I made a base class   bx_generic_apic_c which both kinds can inherit from.  This makes it   type-safe to have pointers to either kind, and they can share some code   for ID setting and such.  Lots of functions are virtual so that you   get the right function even if called on a generic pointer.  Many methods   of the base class are just bx_panics. - you can read and write lots of the local APIC registers, even the ones   I don't use or know what to do with. - now the BX_CPU_C class has its own INTR line, which it uses to detect   interrupts.  This allows the local APIC to interrupt just one CPU. - apic_index array is now an array of bx_generic_apic_c pointers   (either local apics or I/O apics) - read method that handles wierd byte and word reads - added some real interrupt code (trigger_irq, untrigger_irq, acknowledge_int,   an irr[] register) and it sort of works now.<commit_after>#define BX_IN_CPU_METHOD 1
#include "bochs.h"
#include <assert.h>

bx_generic_apic_c *apic_index[APIC_MAX_ID];

bx_generic_apic_c::bx_generic_apic_c ()
{
}

bx_generic_apic_c::~bx_generic_apic_c ()
{
}

void bx_generic_apic_c::init ()
{
  id = APIC_UNKNOWN_ID;
}

void bx_generic_apic_c::set_base (Bit32u newbase)
{
  bx_printf ("relocate APIC id=%d to %8x\n", id, newbase);
  base_addr = newbase;
}

void bx_generic_apic_c::set_id (Bit8u newid) {
  // update apic_index
  if (id != APIC_UNKNOWN_ID) {
    bx_assert (id < APIC_MAX_ID);
    if (apic_index[id] != this)
      bx_panic ("inconsistent APIC id table\n");
    apic_index[id] = NULL;
  }
  id = newid;
  if (apic_index[id] != NULL)
    bx_panic ("duplicate APIC id assigned\n");
  apic_index[id] = this;
}

char *
bx_generic_apic_c::get_name () {
  bx_panic ("get_name called on bx_generic_apic_c base class");
}

Boolean
bx_generic_apic_c::is_selected (Bit32u addr, Bit32u len)
{
  if ((addr & ~0xfff) == get_base ()) {
    if ((addr & 0xf != 0) || (len != 4))
      bx_printf ("warning: misaligned or wrong-size APIC write\n");
    return true;
  }
  return false;
}

void
bx_generic_apic_c::read (Bit32u addr, void *data, unsigned len)
{
  if ((addr & ~0xf) != ((addr+len-1) & ~0xf))
    bx_panic ("APIC read spans 32-bit boundary\n");
  Bit32u value;
  read_aligned (addr, &value, 4);
  if ((addr&3) == 0) {
    *((Bit32u *)data) = value;
    return;
  }
  // handle partial word read
  Bit8u bytes[4];
  bytes[0] = value & 0xff;
  bytes[1] = (value >> 8) & 0xff;
  bytes[2] = (value >> 16) & 0xff;
  bytes[3] = (value >> 24) & 0xff;
  Bit8u *p1 = bytes+(addr&3);
  Bit8u *p2 = (Bit8u *)data;
  for (int i=0; i<len; i++) {
    bx_printf ("apic: Copying byte %02x\n", (unsigned int) *p1);
    *p2++ = *p1++;
  }
}

void bx_generic_apic_c::read_aligned (Bit32u address, Bit32u *data, unsigned len)
{
  bx_panic ("read_aligned not implemented in base class bx_generic_apic_c\n");
}

void bx_generic_apic_c::write(Bit32u address, Bit32u *value, unsigned len)
{
  bx_panic ("write not implemented in base class bx_generic_apic_c\n");
}

void bx_generic_apic_c::startup_msg (Bit32u vector)
{
  bx_panic ("startup message sent to an I/O APIC\n");
}

void bx_generic_apic_c::trigger_irq (unsigned num, unsigned from)
{
  bx_panic ("trigger_irq called on base class\n");
}

void bx_generic_apic_c::untrigger_irq (unsigned num, unsigned from)
{
  bx_panic ("untrigger_irq called on base class");
}

bx_local_apic_c::bx_local_apic_c(BX_CPU_C *mycpu)
{
  cpu = mycpu;
}

void
bx_local_apic_c::init ()
{
  // default address for a local APIC, can be moved
  bx_generic_apic_c::init ();
  base_addr = 0xfee00000;
  err_status = 0;
}

BX_CPU_C
bx_local_apic_c::*get_cpu (Bit8u id)
{
  bx_assert (id < APIC_MAX_ID);
}

bx_local_apic_c::~bx_local_apic_c(void)
{
  // nothing for now
}

void bx_local_apic_c::set_id (Bit8u newid) {
  bx_generic_apic_c::set_id (newid);
  sprintf (cpu->name, "CPU apicid=%02x", (Bit32u)id);
}

char *
bx_local_apic_c::get_name()
{
  return cpu->name;
}

void bx_local_apic_c::write (Bit32u addr, Bit32u *data, unsigned len)
{
  assert (len == 4);
  bx_printf ("write %08x to APIC address %08x\n", *data, addr);
  //assert (!(addr & 0xf));
  addr &= 0xff0;
  switch (addr) {
    case 0x20: // local APIC id
      id = ((*data)>>24) & 0xf;
      break;
    case 0x80: // task priority
      tpr = *data & ~0xff;  // low 8 bits reserved.
      break;
    case 0xb0: // EOI
      // not readable
      bx_printf ("%s: Wrote 0x%04x to EOI\n", cpu->name);
      break;
    case 0xd0: // logical destination
      log_dest = *data;
      break;
    case 0xe0: // destination format
      dest_format = (dest_format & 0x0fffffff) | (*data & 0xf0000000);
      break;
    case 0xf0: // spurious interrupt vector
      spurious_vec = (spurious_vec & 0x0f) | (*data & 0x3f0);
      break;
    case 0x280: // error status reg
      // Here's what the IA-devguide-3 says on p.7-45:
      // The ESR is a read/write register and is reset after being written to by
      // the processor. A write to the ESR must be done just prior to reading the
      // ESR to allow the register to be updated.
      //
      // This doesn't seem clear.  If the write clears the register, then
      // wouldn't you always read zero?  Otherwise, what does the write do?
      // In my model, the write will do nothing.
      break;
    case 0x300: // interrupt command reg 0-31
      {
	icr_low = *data & ~(1<<12);  // force delivery status bit = 0 (idle)
	// and trigger an interrupt to be sent
	int dest_shorthand = (icr_low >> 18) & 3;
	char *dests[4] = {NULL, "self", "all including self", "all except self" };
	char buf[32];
	unsigned int target_id = (icr_high >> 24);
	sprintf (buf, "APIC 0x%02x\n", target_id);
	bx_printf ("APIC 0x%02x sending interrupt to destination %s",
	   id,
	   (dest_shorthand==0) ? buf : dests[dest_shorthand]);
	bx_printf ("low word of APIC 0x%02x ICR = 0x%04x\n", id, icr_low & 0xffff);
	int delivery_mode = (icr_low >> 8) & 7;
	int vector = (icr_low & 0xff);
	if (delivery_mode == 6 && dest_shorthand == 0) {
	  // tell target to start up
	  if (target_id > APIC_MAX_ID) bx_panic ("target apic id out of range\n");
	  bx_generic_apic_c *target = apic_index[target_id];
	  if (target == NULL) bx_panic ("apic target id not found\n");
	  target->startup_msg (vector);
	} else {
	    bx_printf ("APIC operation not supported\n");
	}
      }
      break;
    case 0x310: // interrupt command reg 31-63
      icr_high = *data & 0xff000000;
      break;
    case 0x320: // LVT Timer Reg
      lvt_timer = *data;  //?
      break;
    case 0x330: // LVT Thermal Monitor
      lvt_thermal = *data;  //?
      break;
    case 0x340: // LVT Performance Counter
      lvt_perf = *data;  //?
      break;
    case 0x350: // LVT LINT0 Reg
      lvt_lint0 = *data;  //?
      break;
    case 0x360: // LVT Lint1 Reg
      lvt_lint1 = *data;  //?
      break;
    case 0x370: // LVT Error Reg
      lvt_err = *data;  //?
      break;
    case 0x380: // initial count for timer
      timer_initial = *data;
      break;
    case 0x3e0: // timer divide configuration
      timer_divide = *data;
      break;
    /* all read-only registers go here */
    case 0x30: // local APIC version
    case 0x90: // arbitration priority
    case 0xa0: // processor priority
    // ISRs not writable
    case 0x100: case 0x110: case 0x120: case 0x130:
    case 0x140: case 0x150: case 0x160: case 0x170:
    // TMRs not writable
    case 0x180: case 0x190: case 0x1a0: case 0x1b0:
    case 0x1c0: case 0x1d0: case 0x1e0: case 0x1f0:
    // IRRs not writable
    case 0x200: case 0x210: case 0x220: case 0x230:
    case 0x240: case 0x250: case 0x260: case 0x270:
      // current count for timer
    case 0x390:
      // all read-only registers should fall into this line
      bx_printf ("warning: write to read-only APIC register 0x%02x\n", addr);
      break;
    default:
      bx_panic ("APIC register %08x not implemented\n", addr);
  }
}

void bx_local_apic_c::startup_msg (Bit32u vector)
{
  if (cpu->debug_trap & 0x80000000) {
    cpu->debug_trap &= ~0x80000000;
    cpu->eip = 0;
    cpu->load_seg_reg (&cpu->sregs[BX_SEG_REG_CS], vector*0x100);
    bx_printf ("%s started up at 0x%x by APIC\n", cpu->name, cpu->eip);
  } else {
    bx_printf ("%s started up by APIC, but was not halted at the time\n", cpu->name);
  }
}

void bx_local_apic_c::read_aligned (Bit32u addr, Bit32u *data, unsigned len)
{
  assert (len == 4);
  *data = 0;  // default value for unimplemented registers
  switch (addr & 0xff0) {
  case 0x20: // local APIC id
    *data = (id) << 24; break;
  case 0x30: // local APIC version
    *data = 0x00170011; break;
  case 0x80: // task priority
    *data = tpr; break;
  case 0x90: // arbitration priority
    *data = arb_priority; break;
  case 0xa0: // processor priority
    *data = proc_priority; break;
  case 0xb0: // EOI
    bx_panic ("EOI register not writable\n");
    break;
  case 0xd0: // logical destination
    *data = log_dest; break;
  case 0xe0: // destination format
    *data = dest_format; break;
  case 0xf0: // spurious interrupt vector
    *data = spurious_vec; break;
  // ISRs not writable
  case 0x100: case 0x110: case 0x120: case 0x130:
  case 0x140: case 0x150: case 0x160: case 0x170:
  case 0x180: case 0x190: case 0x1a0: case 0x1b0:
  case 0x1c0: case 0x1d0: case 0x1e0: case 0x1f0:
  case 0x200: case 0x210: case 0x220: case 0x230:
  case 0x240: case 0x250: case 0x260: case 0x270:
    *data = 0;
    bx_printf ("reading ISR,TMR,IRR not implemented");
    break;
  case 0x280: // error status reg
    *data = err_status; break;
  case 0x300: // interrupt command reg 0-31
    *data = icr_low; break;
  case 0x310: // interrupt command reg 31-63
    *data = icr_high; break;
  case 0x320: // LVT Timer Reg
    *data = lvt_timer; break;
  case 0x330: // LVT Thermal Monitor
    *data = lvt_thermal; break;
  case 0x340: // LVT Performance Counter
    *data = lvt_perf; break;
  case 0x350: // LVT LINT0 Reg
    *data = lvt_lint0; break;
  case 0x360: // LVT Lint1 Reg
    *data = lvt_lint1; break;
  case 0x370: // LVT Error Reg
    *data = lvt_err; break;
  case 0x380: // initial count for timer
    *data = timer_initial; break;
  case 0x390: // current count for timer
    *data = timer_current; break;
  case 0x3e0: // timer divide configuration
    *data = timer_divide; break;
  default:
    bx_printf ("APIC register %08x not implemented\n", addr);
  }
  bx_printf ("read from APIC address %08x = %08x\n", addr, *data);
}

int
bx_local_apic_c::highest_priority_int (Bit8u *array)
{
  for (int i=0; i<BX_LOCAL_APIC_MAX_INTS; i++)
    if (array[i]) return i;
  return -1;
}

void bx_local_apic_c::service_local_apic ()
{
  if (cpu->INTR) return;  // INTR already up; do nothing
  // find first interrupt in irr.
  int first_int = highest_priority_int (irr);
  if (first_int < 0) return;   // no interrupts, leave INTR=0
  // interrupt has appeared in irr.  raise INTR.  When the CPU
  // acknowledges, we will run highest_priority_int again and
  // return it.
  cpu->set_INTR (1);
}

void bx_local_apic_c::trigger_irq (unsigned vector, unsigned from)
{
  bx_printf ("Local apic on %s: trigger interrupt %d\n", cpu->name, vector);
  irr[vector] = 1;
  service_local_apic ();
}

void bx_local_apic_c::untrigger_irq (unsigned vector, unsigned from)
{
  bx_printf ("Local apic on %s: untrigger interrupt %d\n", cpu->name, vector);
  // hardware says "no more".  clear the bit.  If the CPU hasn't yet
  // acknowledged the interrupt, it will never be serviced.
  bx_assert (irr[vector] == 1);
  irr[vector] = 0;
}

Bit8u
bx_local_apic_c::acknowledge_int ()
{
  // CPU calls this when it is ready to service one interrupt
  if (!cpu->INTR)
    bx_panic ("%s acknowledged an interrupt, but INTR=0\n", cpu->name);
  int vector = highest_priority_int (irr);
  bx_assert (irr[vector] == 1);
  // currently isr never gets cleared, so no point
  //bx_assert (isr[vector] == 0);
  irr[vector] = 0;
  isr[vector] = 1;
  cpu->INTR = 0;
  service_local_apic ();  // will set INTR again if another is ready
  return vector;
}
<|endoftext|>


<commit_before>/***************************************************************************
    copyright            : (C) 2002 - 2008 by Scott Wheeler
    email                : wheeler@kde.org
 ***************************************************************************/

/***************************************************************************
 *   This library is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License version   *
 *   2.1 as published by the Free Software Foundation.                     *
 *                                                                         *
 *   This library is distributed in the hope that it will be useful, but   *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA         *
 *   02110-1301  USA                                                       *
 *                                                                         *
 *   Alternatively, this file is available under the Mozilla Public        *
 *   License Version 1.1.  You may obtain a copy of the License at         *
 *   http://www.mozilla.org/MPL/                                           *
 ***************************************************************************/

#include <tbytevector.h>

#include "aiffproperties.h"
#include "apeproperties.h"
#include "asfproperties.h"
#include "flacproperties.h"
#include "mp4properties.h"
#include "mpcproperties.h"
#include "mpegproperties.h"
#include "opusproperties.h"
#include "speexproperties.h"
#include "trueaudioproperties.h"
#include "vorbisproperties.h"
#include "wavproperties.h"
#include "wavpackproperties.h"

#include "audioproperties.h"

using namespace TagLib;

class AudioProperties::AudioPropertiesPrivate
{

};

////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////

AudioProperties::~AudioProperties()
{

}

int TagLib::AudioProperties::lengthInSeconds() const
{
  // This is an ugly workaround but we can't add a virtual function.
  // Should be virtual in taglib2.

  if(dynamic_cast<const APE::Properties*>(this))
    return dynamic_cast<const APE::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const ASF::Properties*>(this))
    return dynamic_cast<const ASF::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const FLAC::Properties*>(this))
    return dynamic_cast<const FLAC::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const MP4::Properties*>(this))
    return dynamic_cast<const MP4::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const MPC::Properties*>(this))
    return dynamic_cast<const MPC::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const MPEG::Properties*>(this))
    return dynamic_cast<const MPEG::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const Ogg::Opus::Properties*>(this))
    return dynamic_cast<const Ogg::Opus::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const Ogg::Speex::Properties*>(this))
    return dynamic_cast<const Ogg::Speex::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const TrueAudio::Properties*>(this))
    return dynamic_cast<const TrueAudio::Properties*>(this)->lengthInSeconds();

  else if (dynamic_cast<const RIFF::AIFF::Properties*>(this))
    return dynamic_cast<const RIFF::AIFF::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const RIFF::WAV::Properties*>(this))
    return dynamic_cast<const RIFF::WAV::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const Vorbis::Properties*>(this))
    return dynamic_cast<const Vorbis::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const WavPack::Properties*>(this))
    return dynamic_cast<const WavPack::Properties*>(this)->lengthInSeconds();

  else
    return 0;
}

int TagLib::AudioProperties::lengthInMilliseconds() const
{
  // This is an ugly workaround but we can't add a virtual function.
  // Should be virtual in taglib2.

  if(dynamic_cast<const APE::Properties*>(this))
    return dynamic_cast<const APE::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const ASF::Properties*>(this))
    return dynamic_cast<const ASF::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const FLAC::Properties*>(this))
    return dynamic_cast<const FLAC::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const MP4::Properties*>(this))
    return dynamic_cast<const MP4::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const MPC::Properties*>(this))
    return dynamic_cast<const MPC::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const MPEG::Properties*>(this))
    return dynamic_cast<const MPEG::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const Ogg::Opus::Properties*>(this))
    return dynamic_cast<const Ogg::Opus::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const Ogg::Speex::Properties*>(this))
    return dynamic_cast<const Ogg::Speex::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const TrueAudio::Properties*>(this))
    return dynamic_cast<const TrueAudio::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const RIFF::AIFF::Properties*>(this))
    return dynamic_cast<const RIFF::AIFF::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const RIFF::WAV::Properties*>(this))
    return dynamic_cast<const RIFF::WAV::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const Vorbis::Properties*>(this))
    return dynamic_cast<const Vorbis::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const WavPack::Properties*>(this))
    return dynamic_cast<const WavPack::Properties*>(this)->lengthInMilliseconds();

  else
    return 0;
}

////////////////////////////////////////////////////////////////////////////////
// protected methods
////////////////////////////////////////////////////////////////////////////////

AudioProperties::AudioProperties(ReadStyle) :
  d(0)
{

}
<commit_msg>Small cleanups in audioproperties.cpp.<commit_after>/***************************************************************************
    copyright            : (C) 2002 - 2008 by Scott Wheeler
    email                : wheeler@kde.org
 ***************************************************************************/

/***************************************************************************
 *   This library is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License version   *
 *   2.1 as published by the Free Software Foundation.                     *
 *                                                                         *
 *   This library is distributed in the hope that it will be useful, but   *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA         *
 *   02110-1301  USA                                                       *
 *                                                                         *
 *   Alternatively, this file is available under the Mozilla Public        *
 *   License Version 1.1.  You may obtain a copy of the License at         *
 *   http://www.mozilla.org/MPL/                                           *
 ***************************************************************************/

#include <tbytevector.h>

#include "aiffproperties.h"
#include "apeproperties.h"
#include "asfproperties.h"
#include "flacproperties.h"
#include "mp4properties.h"
#include "mpcproperties.h"
#include "mpegproperties.h"
#include "opusproperties.h"
#include "speexproperties.h"
#include "trueaudioproperties.h"
#include "vorbisproperties.h"
#include "wavproperties.h"
#include "wavpackproperties.h"

#include "audioproperties.h"

using namespace TagLib;

class AudioProperties::AudioPropertiesPrivate
{

};

////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////

AudioProperties::~AudioProperties()
{

}

int AudioProperties::lengthInSeconds() const
{
  // This is an ugly workaround but we can't add a virtual function.
  // Should be virtual in taglib2.

  if(dynamic_cast<const APE::Properties*>(this))
    return dynamic_cast<const APE::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const ASF::Properties*>(this))
    return dynamic_cast<const ASF::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const FLAC::Properties*>(this))
    return dynamic_cast<const FLAC::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const MP4::Properties*>(this))
    return dynamic_cast<const MP4::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const MPC::Properties*>(this))
    return dynamic_cast<const MPC::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const MPEG::Properties*>(this))
    return dynamic_cast<const MPEG::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const Ogg::Opus::Properties*>(this))
    return dynamic_cast<const Ogg::Opus::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const Ogg::Speex::Properties*>(this))
    return dynamic_cast<const Ogg::Speex::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const TrueAudio::Properties*>(this))
    return dynamic_cast<const TrueAudio::Properties*>(this)->lengthInSeconds();

  else if (dynamic_cast<const RIFF::AIFF::Properties*>(this))
    return dynamic_cast<const RIFF::AIFF::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const RIFF::WAV::Properties*>(this))
    return dynamic_cast<const RIFF::WAV::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const Vorbis::Properties*>(this))
    return dynamic_cast<const Vorbis::Properties*>(this)->lengthInSeconds();

  else if(dynamic_cast<const WavPack::Properties*>(this))
    return dynamic_cast<const WavPack::Properties*>(this)->lengthInSeconds();

  else
    return 0;
}

int AudioProperties::lengthInMilliseconds() const
{
  // This is an ugly workaround but we can't add a virtual function.
  // Should be virtual in taglib2.

  if(dynamic_cast<const APE::Properties*>(this))
    return dynamic_cast<const APE::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const ASF::Properties*>(this))
    return dynamic_cast<const ASF::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const FLAC::Properties*>(this))
    return dynamic_cast<const FLAC::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const MP4::Properties*>(this))
    return dynamic_cast<const MP4::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const MPC::Properties*>(this))
    return dynamic_cast<const MPC::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const MPEG::Properties*>(this))
    return dynamic_cast<const MPEG::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const Ogg::Opus::Properties*>(this))
    return dynamic_cast<const Ogg::Opus::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const Ogg::Speex::Properties*>(this))
    return dynamic_cast<const Ogg::Speex::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const TrueAudio::Properties*>(this))
    return dynamic_cast<const TrueAudio::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const RIFF::AIFF::Properties*>(this))
    return dynamic_cast<const RIFF::AIFF::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const RIFF::WAV::Properties*>(this))
    return dynamic_cast<const RIFF::WAV::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const Vorbis::Properties*>(this))
    return dynamic_cast<const Vorbis::Properties*>(this)->lengthInMilliseconds();

  else if(dynamic_cast<const WavPack::Properties*>(this))
    return dynamic_cast<const WavPack::Properties*>(this)->lengthInMilliseconds();

  else
    return 0;
}

////////////////////////////////////////////////////////////////////////////////
// protected methods
////////////////////////////////////////////////////////////////////////////////

AudioProperties::AudioProperties(ReadStyle) :
  d(0)
{

}
<|endoftext|>