<commit_before>#pragma once
#ifndef _QI_SOCK_CONNECTEDSTATE_HPP
#define _QI_SOCK_CONNECTEDSTATE_HPP
#include <memory>
#include <utility>
#include <boost/optional.hpp>
#include <qi/atomic.hpp>
#include <qi/functional.hpp>
#include <qi/future.hpp>
#include <qi/messaging/sock/common.hpp>
#include <qi/messaging/sock/receive.hpp>
#include <qi/messaging/sock/send.hpp>
#include <qi/messaging/sock/traits.hpp>
#include "src/messaging/message.hpp"
#include <qi/url.hpp>

namespace qi
{
  namespace sock
  {

    /// The URL of the endpoint of the given socket.
    /// Precondition: The socket must be connected.
    ///
    /// NetSslSocket S
    template<typename S>
    Url remoteEndpoint(S& socket, bool ssl)
    {
      const auto endpoint = socket.lowest_layer().remote_endpoint();
      return url(endpoint, SslEnabled{ssl});
    }

    /// Ouput of the connected state.
    ///
    /// It contains the socket, error information, and a promise to be set to
    /// indicate the end of the disconnection. This promise will typically be
    /// passed to the disconnecting state and finally set by the disconnected state.
    ///
    /// The only valid operation on the socket is to close it.
    ///
    /// The error message is valid only if there was an error.
    ///
    /// Example:
    /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /// // res is a ConnectedResult<N>
    /// if (res.hasError)
    /// {
    ///   qiLogWarning() << "socket exited connected state with an error: "
    ///     << res.errorMessage;
    /// }
    /// close<N>(res.socket);
    /// res.disconnectedPromise.setValue(nullptr);
    /// // ...
    /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ///
    /// Network N,
    /// With NetSslSocket S:
    ///   S is compatible with N
    template<typename N, typename S>
    struct ConnectedResult
    {
      SocketPtr<S> socket;

      /// If a disconnection was requested, this promise is related to the future
      /// returned to the caller. Setting it will inform the caller that the
      /// disconnection is complete (that is, the socket is in a disconnected state).
      Promise<void> disconnectedPromise;

      bool hasError;
      std::string errorMessage;

      ConnectedResult(SocketPtr<S> s = SocketPtr<S>{})
        : socket(s)
        , hasError(false)
      {
      }
    };

    /// Network N
    /// With NetSslSocket S:
    ///   S is compatible with N
    template<typename N, typename S>
    using SyncConnectedResult = boost::synchronized_value<ConnectedResult<N, S>>;

    /// Network N
    /// With NetSslSocket S:
    ///   S is compatible with N
    template<typename N, typename S>
    using SyncConnectedResultPtr = boost::shared_ptr<SyncConnectedResult<N, S>>;

    boost::optional<qi::int64_t> getSocketTimeWarnThresholdFromEnv();

    /// Connected state of the socket.
    /// Allow to send and receive messages.
    ///
    /// Received messages are exposed via a callback specified at construction.
    ///
    /// You can send messages continuously : they will be enqueued if needed.
    /// By default, enqueued messages are sent as soon as possible, but
    /// you can explicitly ask to stop the queue processing.
    ///
    /// You can request this state to stop, by optionally passing it a Promise
    /// to be set on disconnection.
    ///
    /// A `complete` future is set when the connected state is over.
    /// It contains the socket and a Promise to be set when disconnection is over.
    ///
    /// If an error occurs while sending or receiving, the `complete` future is
    /// set in error.
    ///
    /// Warning: You must call `stop()` before closing the socket, because
    /// closing the socket cause the send and receive handlers to be called with
    /// an 'abort' error, and we don't want to take it into account.
    ///
    /// Usage:
    /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /// auto onReceive = [](ErrorCode e, const Message* msg) {
    ///   // `msg` is valid only if there is no error.
    ///   // Do something with `msg`.
    ///   return true; // Or return false to stop listening to message.
    /// };
    /// Connected<N> c{socketPtr, SslEnabled{true}, maxPayload, onReceive};
    /// // Get a Message msg;
    /// c.send(msg); // Move the message if you can, to avoid a copy.
    /// // Send more messages.
    /// Future<std::pair<SocketPtr<S>, Promise<void>>> futureComplete = c.complete();
    /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ///
    /// Network N
    /// NetSslSocket N
    template<typename N, typename S>
    struct Connected
    {
    private:
      struct Impl : std::enable_shared_from_this<Impl>
      {
        using std::enable_shared_from_this<Impl>::shared_from_this;
        using ReadableMessage = typename SendMessageEnqueue<N, SocketPtr<S>>::ReadableMessage;

        boost::synchronized_value<Promise<SyncConnectedResultPtr<N, S>>> _completePromise;
        SyncConnectedResultPtr<N, S> _result;
        std::atomic<bool> _stopRequested;
        std::atomic<bool> _shuttingdown;
        ReceiveMessageContinuous<N> _receiveMsg;
        SendMessageEnqueue<N, SocketPtr<S>> _sendMsg;

        Impl(const SocketPtr<S>& socket);
        ~Impl();

        template<typename Proc>
        void start(SslEnabled, size_t maxPayload, Proc onReceive, qi::int64_t messageHandlingTimeoutInMus);

        template<typename Msg, typename Proc>
        void send(Msg&& msg, SslEnabled, Proc onSent);

        void stop(Promise<void> disconnectedPromise)
        {
          if (tryRaiseAtomicFlag(_stopRequested))
          {
            (*_result)->disconnectedPromise = disconnectedPromise;

            // The shutdown will cause any pending operation on the socket to fail.
            auto self = shared_from_this();
            ioServiceStranded([=] {
              self->_shuttingdown = true;
              auto socket = (*self->_result)->socket;
              socket->lowest_layer().cancel();
              socket->lowest_layer().shutdown(ShutdownMode<Lowest<S>>::shutdown_both);
            })();
          }
          else
          {
            // The disconnected promise has already been set.
            // Forward the result when we have it.
            adaptFuture((*_result)->disconnectedPromise.future(), disconnectedPromise);
          }
        }

        void setPromise(const sock::ErrorCode<N>&, const Message*);

        SocketPtr<S>& socket()
        {
          return (*_result)->socket;
        }

        template<typename Proc>
        auto ioServiceStranded(Proc&& p)
          -> decltype(StrandTransfo<N>{std::declval<IoService<N>*>()}(std::forward<Proc>(p)))
        {
          return StrandTransfo<N>{&socket()->get_io_service()}(std::forward<Proc>(p));
        }

        DataBoundTransfo<std::shared_ptr<Impl>> lifetimeTransfo()
        {
          return dataBoundTransfo(shared_from_this());
        }

        StrandTransfo<N> syncTransfo()
        {
          return {&(*socket()).get_io_service()};
        }
      };
      std::shared_ptr<Impl> _impl;
    public:
      /// If `onReceive` returns `false`, this stops the message receiving.
      ///
      /// Procedure<bool (ErrorCode<N>, const Message*)> Proc
      template<typename Proc>
      Connected(const SocketPtr<S>&, SslEnabled ssl, size_t maxPayload, const Proc& onReceive,
        qi::int64_t messageHandlingTimeoutInMus = getSocketTimeWarnThresholdFromEnv().value_or(0));

      /// If `onSent` returns false, the processing of enqueued messages stops.
      ///
      /// Procedure<bool (ErrorCode<N>, std::list<Message>::const_iterator)>
      template<typename Msg, typename Proc = NoOpProcedure<bool (ErrorCode<N>, std::list<Message>::const_iterator)>>
      void send(Msg&& msg, SslEnabled ssl, const Proc& onSent = {true})
      {
        return _impl->send(std::forward<Msg>(msg), ssl, onSent);
      }
      Future<SyncConnectedResultPtr<N, S>> complete() const
      {
        return _impl->_completePromise->future();
      }
      Url remoteEndpoint(SslEnabled ssl) const
      {
        return sock::remoteEndpoint(*_impl->socket(), *ssl);
      }
      void stop(Promise<void> disconnectedPromise = Promise<void>{})
      {
        _impl->stop(disconnectedPromise);
      }
      template<typename Proc>
      auto ioServiceStranded(Proc&& p)
        -> decltype(_impl->ioServiceStranded(std::forward<Proc>(p)))
      {
        return _impl->ioServiceStranded(std::forward<Proc>(p));
      }
    };

    template<typename N, typename S>
    template<typename Proc>
    Connected<N, S>::Connected(const SocketPtr<S>& socket, SslEnabled ssl, size_t maxPayload,
        const Proc& onReceive, qi::int64_t messageHandlingTimeoutInMus)
      : _impl(std::make_shared<Impl>(socket))
    {
      _impl->start(ssl, maxPayload, onReceive, messageHandlingTimeoutInMus);
    }

    template<typename N, typename S>
    Connected<N, S>::Impl::Impl(const SocketPtr<S>& s)
      : _result{ boost::make_shared<SyncConnectedResult<N, S>>(ConnectedResult<N, S>{ s }) }
      , _stopRequested(false)
      , _shuttingdown(false)
      , _sendMsg{s}
    {
    }

    template<typename N, typename S>
    void Connected<N, S>::Impl::setPromise(const sock::ErrorCode<N>& error, const Message* msg)
    {
      auto prom = _completePromise.synchronize();
      if (!prom->future().isRunning()) // promise already set
        return;
      const bool stopAsked = _stopRequested.load() && _shuttingdown.load();
      const bool hasError = error || !msg;
      if (!stopAsked && hasError)
      {
        auto syncRes = _result->synchronize();
        syncRes->hasError = true;
        syncRes->errorMessage = error.message();
      }
      prom->setValue(_result);
    }

    template<typename N, typename S>
    template<typename Proc>
    void Connected<N, S>::Impl::start(SslEnabled ssl, size_t maxPayload, Proc onReceive,
        qi::int64_t messageHandlingTimeoutInMus)
    {
      auto self = shared_from_this();
      auto life = lifetimeTransfo();
      auto sync = syncTransfo();

      // We preventively strand the first call.
      sync(life([=]() mutable {
        _receiveMsg(socket(), ssl, maxPayload,
          [=](sock::ErrorCode<N> e, const Message* msg) mutable { // onReceived
            const bool mustContinue = !_shuttingdown.load() && onReceive(e, msg);
            if (!mustContinue)
            {
              self->setPromise(e, msg);
              return false; // We must not continue to receive messages.
            }
            return true; // Otherwise, we continue to receive messages.
          },
          life,
          sync
        );
      }))();
    }

    template<typename N, typename S>
    Connected<N, S>::Impl::~Impl()
    {
    }

    template<typename N, typename S>
    template<typename Msg, typename Proc>
    void Connected<N, S>::Impl::send(Msg&& msg, SslEnabled ssl, Proc onSent)
    {
      using SendMessage = decltype(_sendMsg);
      using ReadableMessage = typename SendMessage::ReadableMessage;
      auto self = shared_from_this();
      auto life = lifetimeTransfo();
      auto sync = syncTransfo();

      // We preventively strand the first call.
      sync(life([=]() mutable {
        _sendMsg(std::forward<Msg>(msg), ssl,
          [=](const ErrorCode<N>& e, const ReadableMessage& ptrMsg) mutable { // onSent
            const bool mustContinue = !_shuttingdown.load() && onSent(e, ptrMsg);
            if (!mustContinue)
            {
              self->setPromise(e, &msg);
              return false; // We must not continue to send messages.
            }
            return true; // Otherwise, we continue to send messages.
          },
          life,
          sync
        );
      }))();
    }
}} // namespace qi::sock

#endif // _QI_SOCK_CONNECTEDSTATE_HPP
<commit_msg>messaging: Removes unnecessary message copies.<commit_after>#pragma once
#ifndef _QI_SOCK_CONNECTEDSTATE_HPP
#define _QI_SOCK_CONNECTEDSTATE_HPP
#include <memory>
#include <utility>
#include <boost/optional.hpp>
#include <qi/atomic.hpp>
#include <qi/functional.hpp>
#include <qi/future.hpp>
#include <qi/messaging/sock/common.hpp>
#include <qi/messaging/sock/receive.hpp>
#include <qi/messaging/sock/send.hpp>
#include <qi/messaging/sock/traits.hpp>
#include "src/messaging/message.hpp"
#include <qi/url.hpp>

namespace qi
{
  namespace sock
  {

    /// The URL of the endpoint of the given socket.
    /// Precondition: The socket must be connected.
    ///
    /// NetSslSocket S
    template<typename S>
    Url remoteEndpoint(S& socket, bool ssl)
    {
      const auto endpoint = socket.lowest_layer().remote_endpoint();
      return url(endpoint, SslEnabled{ssl});
    }

    /// Ouput of the connected state.
    ///
    /// It contains the socket, error information, and a promise to be set to
    /// indicate the end of the disconnection. This promise will typically be
    /// passed to the disconnecting state and finally set by the disconnected state.
    ///
    /// The only valid operation on the socket is to close it.
    ///
    /// The error message is valid only if there was an error.
    ///
    /// Example:
    /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /// // res is a ConnectedResult<N>
    /// if (res.hasError)
    /// {
    ///   qiLogWarning() << "socket exited connected state with an error: "
    ///     << res.errorMessage;
    /// }
    /// close<N>(res.socket);
    /// res.disconnectedPromise.setValue(nullptr);
    /// // ...
    /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ///
    /// Network N,
    /// With NetSslSocket S:
    ///   S is compatible with N
    template<typename N, typename S>
    struct ConnectedResult
    {
      SocketPtr<S> socket;

      /// If a disconnection was requested, this promise is related to the future
      /// returned to the caller. Setting it will inform the caller that the
      /// disconnection is complete (that is, the socket is in a disconnected state).
      Promise<void> disconnectedPromise;

      bool hasError;
      std::string errorMessage;

      ConnectedResult(SocketPtr<S> s = SocketPtr<S>{})
        : socket(s)
        , hasError(false)
      {
      }
    };

    /// Network N
    /// With NetSslSocket S:
    ///   S is compatible with N
    template<typename N, typename S>
    using SyncConnectedResult = boost::synchronized_value<ConnectedResult<N, S>>;

    /// Network N
    /// With NetSslSocket S:
    ///   S is compatible with N
    template<typename N, typename S>
    using SyncConnectedResultPtr = boost::shared_ptr<SyncConnectedResult<N, S>>;

    boost::optional<qi::int64_t> getSocketTimeWarnThresholdFromEnv();

    /// Connected state of the socket.
    /// Allow to send and receive messages.
    ///
    /// Received messages are exposed via a callback specified at construction.
    ///
    /// You can send messages continuously : they will be enqueued if needed.
    /// By default, enqueued messages are sent as soon as possible, but
    /// you can explicitly ask to stop the queue processing.
    ///
    /// You can request this state to stop, by optionally passing it a Promise
    /// to be set on disconnection.
    ///
    /// A `complete` future is set when the connected state is over.
    /// It contains the socket and a Promise to be set when disconnection is over.
    ///
    /// If an error occurs while sending or receiving, the `complete` future is
    /// set in error.
    ///
    /// Warning: You must call `stop()` before closing the socket, because
    /// closing the socket cause the send and receive handlers to be called with
    /// an 'abort' error, and we don't want to take it into account.
    ///
    /// Usage:
    /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /// auto onReceive = [](ErrorCode e, const Message* msg) {
    ///   // `msg` is valid only if there is no error.
    ///   // Do something with `msg`.
    ///   return true; // Or return false to stop listening to message.
    /// };
    /// Connected<N> c{socketPtr, SslEnabled{true}, maxPayload, onReceive};
    /// // Get a Message msg;
    /// c.send(msg); // Move the message if you can, to avoid a copy.
    /// // Send more messages.
    /// Future<std::pair<SocketPtr<S>, Promise<void>>> futureComplete = c.complete();
    /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ///
    /// Network N
    /// NetSslSocket N
    template<typename N, typename S>
    struct Connected
    {
    private:
      struct Impl : std::enable_shared_from_this<Impl>
      {
        using std::enable_shared_from_this<Impl>::shared_from_this;
        using ReadableMessage = typename SendMessageEnqueue<N, SocketPtr<S>>::ReadableMessage;

        boost::synchronized_value<Promise<SyncConnectedResultPtr<N, S>>> _completePromise;
        SyncConnectedResultPtr<N, S> _result;
        std::atomic<bool> _stopRequested;
        std::atomic<bool> _shuttingdown;
        ReceiveMessageContinuous<N> _receiveMsg;
        SendMessageEnqueue<N, SocketPtr<S>> _sendMsg;

        Impl(const SocketPtr<S>& socket);
        ~Impl();

        template<typename Proc>
        void start(SslEnabled, size_t maxPayload, Proc onReceive, qi::int64_t messageHandlingTimeoutInMus);

        template<typename Msg, typename Proc>
        void send(Msg&& msg, SslEnabled, Proc onSent);

        void stop(Promise<void> disconnectedPromise)
        {
          if (tryRaiseAtomicFlag(_stopRequested))
          {
            (*_result)->disconnectedPromise = disconnectedPromise;

            // The shutdown will cause any pending operation on the socket to fail.
            auto self = shared_from_this();
            ioServiceStranded([=] {
              self->_shuttingdown = true;
              auto socket = (*self->_result)->socket;
              socket->lowest_layer().cancel();
              socket->lowest_layer().shutdown(ShutdownMode<Lowest<S>>::shutdown_both);
            })();
          }
          else
          {
            // The disconnected promise has already been set.
            // Forward the result when we have it.
            adaptFuture((*_result)->disconnectedPromise.future(), disconnectedPromise);
          }
        }

        void setPromise(const sock::ErrorCode<N>&);

        SocketPtr<S>& socket()
        {
          return (*_result)->socket;
        }

        template<typename Proc>
        auto ioServiceStranded(Proc&& p)
          -> decltype(StrandTransfo<N>{std::declval<IoService<N>*>()}(std::forward<Proc>(p)))
        {
          return StrandTransfo<N>{&socket()->get_io_service()}(std::forward<Proc>(p));
        }

        DataBoundTransfo<std::shared_ptr<Impl>> lifetimeTransfo()
        {
          return dataBoundTransfo(shared_from_this());
        }

        StrandTransfo<N> syncTransfo()
        {
          return {&(*socket()).get_io_service()};
        }
      };
      std::shared_ptr<Impl> _impl;
    public:
      /// If `onReceive` returns `false`, this stops the message receiving.
      ///
      /// Procedure<bool (ErrorCode<N>, const Message*)> Proc
      template<typename Proc>
      Connected(const SocketPtr<S>&, SslEnabled ssl, size_t maxPayload, const Proc& onReceive,
        qi::int64_t messageHandlingTimeoutInMus = getSocketTimeWarnThresholdFromEnv().value_or(0));

      /// If `onSent` returns false, the processing of enqueued messages stops.
      ///
      /// Procedure<bool (ErrorCode<N>, std::list<Message>::const_iterator)>
      template<typename Msg, typename Proc = NoOpProcedure<bool (ErrorCode<N>, std::list<Message>::const_iterator)>>
      void send(Msg&& msg, SslEnabled ssl, const Proc& onSent = {true})
      {
        return _impl->send(std::forward<Msg>(msg), ssl, onSent);
      }
      Future<SyncConnectedResultPtr<N, S>> complete() const
      {
        return _impl->_completePromise->future();
      }
      Url remoteEndpoint(SslEnabled ssl) const
      {
        return sock::remoteEndpoint(*_impl->socket(), *ssl);
      }
      void stop(Promise<void> disconnectedPromise = Promise<void>{})
      {
        _impl->stop(disconnectedPromise);
      }
      template<typename Proc>
      auto ioServiceStranded(Proc&& p)
        -> decltype(_impl->ioServiceStranded(std::forward<Proc>(p)))
      {
        return _impl->ioServiceStranded(std::forward<Proc>(p));
      }
    };

    template<typename N, typename S>
    template<typename Proc>
    Connected<N, S>::Connected(const SocketPtr<S>& socket, SslEnabled ssl, size_t maxPayload,
        const Proc& onReceive, qi::int64_t messageHandlingTimeoutInMus)
      : _impl(std::make_shared<Impl>(socket))
    {
      _impl->start(ssl, maxPayload, onReceive, messageHandlingTimeoutInMus);
    }

    template<typename N, typename S>
    Connected<N, S>::Impl::Impl(const SocketPtr<S>& s)
      : _result{ boost::make_shared<SyncConnectedResult<N, S>>(ConnectedResult<N, S>{ s }) }
      , _stopRequested(false)
      , _shuttingdown(false)
      , _sendMsg{s}
    {
    }

    template<typename N, typename S>
    void Connected<N, S>::Impl::setPromise(const sock::ErrorCode<N>& error)
    {
      auto prom = _completePromise.synchronize();
      if (!prom->future().isRunning()) // promise already set
        return;
      const bool stopAsked = _stopRequested.load() && _shuttingdown.load();
      if (!stopAsked && error)
      {
        auto syncRes = _result->synchronize();
        syncRes->hasError = true;
        syncRes->errorMessage = error.message();
      }
      prom->setValue(_result);
    }

    template<typename N, typename S>
    template<typename Proc>
    void Connected<N, S>::Impl::start(SslEnabled ssl, size_t maxPayload, Proc onReceive,
        qi::int64_t messageHandlingTimeoutInMus)
    {
      auto self = shared_from_this();
      auto life = lifetimeTransfo();
      auto sync = syncTransfo();

      // We preventively strand the first call.
      sync(life([=]() mutable {
        _receiveMsg(socket(), ssl, maxPayload,
          [=](sock::ErrorCode<N> e, const Message* msg) mutable { // onReceived
            const bool mustContinue = !_shuttingdown.load() && onReceive(e, msg);
            if (!mustContinue)
            {
              self->setPromise(e);
              return false; // We must not continue to receive messages.
            }
            return true; // Otherwise, we continue to receive messages.
          },
          life,
          sync
        );
      }))();
    }

    template<typename N, typename S>
    Connected<N, S>::Impl::~Impl()
    {
    }

    template<typename N, typename S>
    template<typename Msg, typename Proc>
    void Connected<N, S>::Impl::send(Msg&& msg, SslEnabled ssl, Proc onSent)
    {
      using SendMessage = decltype(_sendMsg);
      using ReadableMessage = typename SendMessage::ReadableMessage;
      auto self = shared_from_this();
      auto life = lifetimeTransfo();
      auto sync = syncTransfo();

      // We preventively strand the first call.
      sync(life([=]() mutable {
        _sendMsg(std::move(msg), ssl,
          [=](const ErrorCode<N>& e, const ReadableMessage& ptrMsg) mutable { // onSent
            const bool mustContinue = !_shuttingdown.load() && onSent(e, ptrMsg);
            if (!mustContinue)
            {
              self->setPromise(e);
              return false; // We must not continue to send messages.
            }
            return true; // Otherwise, we continue to send messages.
          },
          life,
          sync
        );
      }))();
    }
}} // namespace qi::sock

#endif // _QI_SOCK_CONNECTEDSTATE_HPP
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <string>
#include "LinkerEngine.h"
#include "ModuleEngine.h"
#include "ObjectCode.h"
using std::cout;
using std::cin;
using std::advance;

using std::string;

int main(int argc, char *argv[]) {
	int pause;
	string fileA = "arquivoTesteA.o";
	string fileB = "arquivoTesteB.o";

	auto linker = new LinkerEngine;
	auto mod_A_teste = new ModuleEngine(fileA);
	linker->AddModule(*mod_A_teste);

	auto mod_B_teste = new ModuleEngine(fileB);
	linker->AddModule(*mod_B_teste);

	linker->Merge();

	cin >> pause;

	return 0;
}

<commit_msg>Main para ser a copia do preprocrssador do Pedro<commit_after>#include <stdio.h>
#include <fstream>
#include "MacroAssemblerLibraries.h"
#include <stdlib.h>
#include <string>
#include "LinkerEngine.h"
#include "ModuleEngine.h"
#include "ObjectCode.h"
using std::cout;
using std::cin;
using std::advance;
using std::string;
using std::ifstream;
ifstream VerifyFile(const char* fileName);

int main(int argc, char *argv[]) {
#ifdef _DEBUG
	//seta programaticamente os argumentos em modo debug
	argv[0] = "arquivoTesteA.o";
	argv[1] = "arquivoTesteB.o";
	argv[2] = "arquivoTeste.exe";
#else
	//pega os argumentos da linha de comando em modo release
	if (argc < 4) {
		printf("Selecione ate 3 arquivos objetos para o ligador,juntamente com o arquivo .e ligador:\n");
		printf("cmd>Montador <Arquivo de Entrada1> <Arquivo de Entrada2> <Arquivo de Saida>\n");
		return 0;
	}
	if (argc > 3) {
		printf("Selecione ate 3 arquivos objetos para o ligador,juntamente com o arquivo .e ligador:\n");
		printf("cmd>Montador <Arquivo de Entrada1> <Arquivo de Entrada2><Arquivo de Entrada3> <Arquivo de Saida>\n");
		return 0;
	}
#endif // DEBUG
	for (int i = 0; i < 2; i++) {
		ifstream& fileStream = VerifyFile(argv[i]);
	}
	auto linker = new LinkerEngine;
	for (int  i = 0; i < 2; i++) {
		auto File = new ModuleEngine(argv[i]);
		linker->AddModule(*File);
	}
	linker->Merge();

	getchar();
	return 0;
}

/// <summary>
/// Verifica a extenso do arquivo passado e se ele foi encontrado
/// </summary>
/// <param name="fileName">nome do arquivo</param>
/// <returns>Uma stream para o arquivo o caso a verificao seja bem sucedida. Sai do programa caso contrario</returns>
ifstream VerifyFile(const char* fileName) {
	string fileNameS(fileName);
	size_t extensionIndex = fileNameS.find_last_of(".");

	string extension = StringLibrary::ToLower(fileNameS.substr(extensionIndex + 1));

	if (extension != "o") {
		printf("O ligador aceita somente arquivos .o para a leitura \nExtensao do arquivo passado: .%s\n", extension.c_str());
		exit(0);
	}

	ifstream file(fileName);
	if (!file.is_open()) {
		printf("O arquivo especificado %s nao existe\n", fileName);
		exit(0);
	}

	return file;
}

	/*
	int pause;
	string fileA = "arquivoTesteA.o";
	string fileB = "arquivoTesteB.o";

	auto linker = new LinkerEngine;
	auto mod_A_teste = new ModuleEngine(fileA);
	linker->AddModule(*mod_A_teste);

	auto mod_B_teste = new ModuleEngine(fileB);
	linker->AddModule(*mod_B_teste);

	linker->Merge();

	cin >> pause;

	return 0;
}*/

<|endoftext|>


<commit_before>// [WriteFile Name=ConfigureSubnetworkTrace, Category=Analysis]
// [Legal]
// Copyright 2020 Esri.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// [Legal]

#ifdef PCH_BUILD
#include "pch.hpp"
#endif // PCH_BUILD

#include "ConfigureSubnetworkTrace.h"

#include "CodedValueDomain.h"
#include "TaskWatcher.h"
#include "UtilityAssetGroup.h"
#include "UtilityAssetType.h"
#include "UtilityCategory.h"
#include "UtilityCategoryComparison.h"
#include "UtilityDomainNetwork.h"
#include "UtilityElement.h"
#include "UtilityElementTraceResult.h"
#include "UtilityNetwork.h"
#include "UtilityNetworkDefinition.h"
#include "UtilityNetworkSource.h"
#include "UtilityNetworkTypes.h"
#include "UtilityTerminal.h"
#include "UtilityTerminalConfiguration.h"
#include "UtilityTier.h"
#include "UtilityTraceAndCondition.h"
#include "UtilityTraceConfiguration.h"
#include "UtilityTraceOrCondition.h"
#include "UtilityTraceParameters.h"
#include "UtilityTraceResultListModel.h"
#include "UtilityTraversability.h"

#include <QQmlEngine>

using namespace Esri::ArcGISRuntime;
QString expressionToString(UtilityTraceConditionalExpression* expression);
QString comparisonOperatorToString(const UtilityAttributeComparisonOperator& comparisonOperator);
QVariant convertToDataType(const QVariant& value, const Esri::ArcGISRuntime::UtilityNetworkAttributeDataType& dataType);

ConfigureSubnetworkTrace::ConfigureSubnetworkTrace(QObject* parent /* = nullptr */):
  QObject(parent)
{
  m_utilityNetwork = new UtilityNetwork(m_featureLayerUrl, this);

  connect(m_utilityNetwork, &UtilityNetwork::doneLoading, this, &ConfigureSubnetworkTrace::onUtilityNetworkLoaded);

  connect(m_utilityNetwork, &UtilityNetwork::traceCompleted, this, &ConfigureSubnetworkTrace::onTraceCompleted);

  m_utilityNetwork->load();
}

QString expressionToString(UtilityTraceConditionalExpression* expression)
{
  switch (expression->traceConditionType())
  {
    case UtilityTraceConditionType::UtilityNetworkAttributeComparison:
    {
      const UtilityNetworkAttributeComparison* attributeExpression = static_cast<UtilityNetworkAttributeComparison*>(expression);
      const UtilityNetworkAttribute* networkAttribute = attributeExpression->networkAttribute();
      const UtilityNetworkAttribute* otherNetworkAttribute = attributeExpression->otherNetworkAttribute();
      const Domain networkDomain = networkAttribute->domain();
      const QString operatorAsString = comparisonOperatorToString(attributeExpression->comparisonOperator());

      // check if attribute domain is a coded value domain.
      if (!networkDomain.isEmpty() && (networkDomain.domainType() == DomainType::CodedValueDomain))
      {
        const CodedValueDomain codedValueDomain = static_cast<CodedValueDomain>(networkDomain);
        const QList<CodedValue> codedValues = codedValueDomain.codedValues();

        // get the coded value using the value as the index for the list of coded values
        const QString codedValueName = codedValues[attributeExpression->value().toInt()].name();

        return QString("`%1` %2 `%3`").arg(networkAttribute->name(), operatorAsString, codedValueName);
      }
      else
      {
        if (otherNetworkAttribute)
        {
          return QString("`%1` %2 `%3`").arg(networkAttribute->name(), operatorAsString, otherNetworkAttribute->name());
        }
        return QString("`%1` %2 `%3`").arg(networkAttribute->name(), operatorAsString, attributeExpression->value().toString());
      }
    }
    case UtilityTraceConditionType::UtilityCategoryComparison:
    {
      const UtilityCategoryComparison* comparisonExpression = static_cast<UtilityCategoryComparison*>(expression);

      return QString("`%1` %2").arg(comparisonExpression->category()->name(), (comparisonExpression->comparisonOperator() == UtilityCategoryComparisonOperator::Exists) ? "Exists" : "DoesNotExist");
    }
    case UtilityTraceConditionType::UtilityTraceAndCondition:
    {
      const UtilityTraceAndCondition* andExpression = static_cast<UtilityTraceAndCondition*>(expression);

      return QString("(%1) AND\n (%2)").arg(expressionToString(andExpression->leftExpression()), expressionToString(andExpression->rightExpression()));
    }
    case UtilityTraceConditionType::UtilityTraceOrCondition:
    {
      const UtilityTraceOrCondition* orExpression = static_cast<UtilityTraceOrCondition*>(expression);
      return QString("(%1) OR\n (%2)").arg(expressionToString(orExpression->leftExpression()), expressionToString(orExpression->rightExpression()));
    }
    default:
      return QString("Unknown trace conditional expression");
  }
}

QString comparisonOperatorToString(const UtilityAttributeComparisonOperator& comparisonOperator)
{
  switch (comparisonOperator)
  {
    case UtilityAttributeComparisonOperator::Equal:
      return QString("Equal");
    case UtilityAttributeComparisonOperator::NotEqual:
      return QString("NotEqual");
    case UtilityAttributeComparisonOperator::GreaterThan:
      return QString("GreaterThan");
    case UtilityAttributeComparisonOperator::GreaterThanEqual:
      return QString("GreaterThanEqual");
    case UtilityAttributeComparisonOperator::LessThan:
      return QString("LessThan");
    case UtilityAttributeComparisonOperator::LessThanEqual:
      return QString("LessThanEqual");
    case UtilityAttributeComparisonOperator::IncludesTheValues:
      return QString("IncludesTheValues");
    case UtilityAttributeComparisonOperator::DoesNotIncludeTheValues:
      return QString("DoesNotIncludeTheValues");
    case UtilityAttributeComparisonOperator::IncludesAny:
      return QString("IncludesAny");
    case UtilityAttributeComparisonOperator::DoesNotIncludeAny:
      return QString("DoesNotIncludeAny");
    default:
      return QString("Unknown comparison operator");
  }
}

QVariant convertToDataType(const QVariant& value, const Esri::ArcGISRuntime::UtilityNetworkAttributeDataType& dataType)
{
  switch (dataType)
  {
    case UtilityNetworkAttributeDataType::Integer:
    {
      return static_cast<int>(value.toDouble());
    }
    case UtilityNetworkAttributeDataType::Float:
    {
      return value.toFloat();
    }
    case UtilityNetworkAttributeDataType::Double:
    {
      return value.toDouble();
    }
    case UtilityNetworkAttributeDataType::Boolean:
    {
      return value.toBool();
    }
    default:
      return QVariant();
  }
}

void ConfigureSubnetworkTrace::codedValueOrInputText(const QString& currentText)
{
  // Update the UI to show the correct value entry for the attribute.
  if (m_networkDefinition)
  {
    const Domain domain = m_networkDefinition->networkAttribute(currentText)->domain();
    if (!domain.isEmpty() && (domain.domainType() == DomainType::CodedValueDomain))
    {
      m_valueSelectionListModel.clear();
      const CodedValueDomain codedValueDomain = static_cast<CodedValueDomain>(domain);

      for (CodedValue codedValue: codedValueDomain.codedValues())
        m_valueSelectionListModel.append(codedValue.name());

      m_textFieldVisible = false;
    }
    else
    {
      m_textFieldVisible = true;
    }
    emit valueSelectionListModelChanged();
    emit textFieldVisibleChanged();
  }
}

void ConfigureSubnetworkTrace::addCondition(const QString& selectedAttribute, int selectedOperator, const QVariant& selectedValue)
{
  // NOTE: You may also create a UtilityCategoryComparison with UtilityNetworkDefinition.Categories and UtilityCategoryComparisonOperator.

  UtilityNetworkAttribute* selectedNetworkAttribute = m_networkDefinition->networkAttribute(selectedAttribute);
  const QVariant convertedSelectedValue = convertToDataType(selectedValue, selectedNetworkAttribute->dataType());

  if (convertedSelectedValue.isNull())
  {
    m_dialogText = "Unknow network attribute data type";
    emit dialogTextChanged();
    emit showDialog();
    return;
  }

  const UtilityAttributeComparisonOperator selectedOperatorEnum = static_cast<UtilityAttributeComparisonOperator>(selectedOperator);

  // NOTE: You may also create a UtilityNetworkAttributeComparison with another NetworkAttribute.
  UtilityTraceConditionalExpression* expression = new UtilityNetworkAttributeComparison(selectedNetworkAttribute, selectedOperatorEnum, convertedSelectedValue, this);

  UtilityTraceConditionalExpression* otherExpression = static_cast<UtilityTraceConditionalExpression*>(m_traceConfiguration->traversability()->barriers());

  // NOTE: You may also combine expressions with UtilityTraceAndCondition
  UtilityTraceConditionalExpression* combineExpressions = new UtilityTraceOrCondition(otherExpression, expression, this);

  m_expressionBuilder = expressionToString(combineExpressions);
  emit expressionBuilderChanged();

  m_traceConfiguration->traversability()->setBarriers(combineExpressions);
}

void ConfigureSubnetworkTrace::changeIncludeBarriersState(bool includeBarriers)
{
  m_traceConfiguration->setIncludeBarriers(includeBarriers);
}

void ConfigureSubnetworkTrace::changeIncludeContainersState(bool includeContainers)
{
  m_traceConfiguration->setIncludeContainers(includeContainers);
}

void ConfigureSubnetworkTrace::reset()
{
  // Reset the barrier condition to the initial value.
  m_traceConfiguration->traversability()->setBarriers(m_initialExpression);
  m_expressionBuilder.clear();
  m_expressionBuilder = expressionToString(static_cast<UtilityTraceConditionalExpression*>(m_initialExpression));
  emit expressionBuilderChanged();
}

void ConfigureSubnetworkTrace::trace()
{
  if (!m_utilityNetwork || !m_utilityElementStartingLocation)
  {
    return;
  }

  m_busy = true;
  emit busyChanged();
  const QList<UtilityElement*> startingLocations {m_utilityElementStartingLocation};
  // Create utility trace parameters for the starting location.
  m_traceParams = new UtilityTraceParameters(UtilityTraceType::Subnetwork, startingLocations, this);
  m_traceParams->setTraceConfiguration(m_traceConfiguration);

  // trace the network
  m_utilityNetwork->trace(m_traceParams);
}

void ConfigureSubnetworkTrace::onTraceCompleted()
{
  if (m_utilityNetwork->traceResult()->isEmpty())
  {
    m_dialogText = "No results returned";
    emit dialogTextChanged();
    emit showDialog();
  }
  // Get the first result.
  UtilityTraceResult* result = m_utilityNetwork->traceResult()->at(0);

  const QList<UtilityElement*> elements = static_cast<UtilityElementTraceResult*>(result)->elements(this);

  // Display the number of elements found by the trace.
  m_dialogText = QString("%1 elements found.").arg(elements.length());
  m_busy = false;
  emit dialogTextChanged();
  emit showDialog();
  emit busyChanged();
}

void ConfigureSubnetworkTrace::onUtilityNetworkLoaded(const Error& e)
{
  if (!e.isEmpty())
  {
    m_dialogText = QString("%1 - %2").arg(e.message(), e.additionalMessage());
    m_busy = false;
    emit dialogTextChanged();
    emit showDialog();
    emit busyChanged();
    return;
  }

  m_busy = false;
  emit busyChanged();
  m_networkDefinition = m_utilityNetwork->definition();

  // Build the choice lists for network attribute comparison.
  for (UtilityNetworkAttribute* networkAttribute : m_networkDefinition->networkAttributes())
  {
    if (!networkAttribute->isSystemDefined())
      m_attributeListModel.append(networkAttribute->name());
  }
  emit attributeListModelChanged();

  // Create a default starting location.
  const UtilityNetworkSource* networkSource = m_networkDefinition->networkSource(m_deviceTableName);
  const UtilityAssetGroup* assetGroup = networkSource->assetGroup(m_assetGroupName);
  UtilityAssetType* assetType = assetGroup->assetType(m_assetTypeName);
  m_utilityElementStartingLocation = m_utilityNetwork->createElementWithAssetType(assetType, m_gloabId);

  QList<UtilityTerminal*> terminals = m_utilityElementStartingLocation->assetType()->terminalConfiguration()->terminals();

  // Set the terminal for this location. (For our case, we use the 'Load' terminal.)
  auto terminal = std::find_if(terminals.begin(), terminals.end(), [](UtilityTerminal* terminal)
  {
      return terminal->name() == "Load";
  });

  m_utilityElementStartingLocation->setTerminal(static_cast<UtilityTerminal*>(*terminal));

  // Get a default trace configuration from a tier to update the UI.
  const UtilityDomainNetwork* domainNetwork = m_networkDefinition->domainNetwork(m_domainNetworkName);
  const UtilityTier* utilityTierSource = domainNetwork->tier(m_tierName);

  // Set the trace configuration.
  m_traceConfiguration = utilityTierSource->traceConfiguration();

  m_initialExpression = m_traceConfiguration->traversability()->barriers();

  if (m_initialExpression)
  {
    m_expressionBuilder = expressionToString(static_cast<UtilityTraceConditionalExpression*>(m_initialExpression));
    emit expressionBuilderChanged();
  }

  // Set the traversability scope.
  utilityTierSource->traceConfiguration()->traversability()->setScope(UtilityTraversabilityScope::Junctions);
}

ConfigureSubnetworkTrace::~ConfigureSubnetworkTrace() = default;

void ConfigureSubnetworkTrace::init()
{
  qmlRegisterType<ConfigureSubnetworkTrace>("Esri.Samples", 1, 0, "ConfigureSubnetworkTraceSample");
}
<commit_msg>adding algorithm library.<commit_after>// [WriteFile Name=ConfigureSubnetworkTrace, Category=Analysis]
// [Legal]
// Copyright 2020 Esri.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// [Legal]

#ifdef PCH_BUILD
#include "pch.hpp"
#endif // PCH_BUILD

#include "ConfigureSubnetworkTrace.h"

#include "CodedValueDomain.h"
#include "TaskWatcher.h"
#include "UtilityAssetGroup.h"
#include "UtilityAssetType.h"
#include "UtilityCategory.h"
#include "UtilityCategoryComparison.h"
#include "UtilityDomainNetwork.h"
#include "UtilityElement.h"
#include "UtilityElementTraceResult.h"
#include "UtilityNetwork.h"
#include "UtilityNetworkDefinition.h"
#include "UtilityNetworkSource.h"
#include "UtilityNetworkTypes.h"
#include "UtilityTerminal.h"
#include "UtilityTerminalConfiguration.h"
#include "UtilityTier.h"
#include "UtilityTraceAndCondition.h"
#include "UtilityTraceConfiguration.h"
#include "UtilityTraceOrCondition.h"
#include "UtilityTraceParameters.h"
#include "UtilityTraceResultListModel.h"
#include "UtilityTraversability.h"

#include <QQmlEngine>
#include <algorithm>

using namespace Esri::ArcGISRuntime;
QString expressionToString(UtilityTraceConditionalExpression* expression);
QString comparisonOperatorToString(const UtilityAttributeComparisonOperator& comparisonOperator);
QVariant convertToDataType(const QVariant& value, const Esri::ArcGISRuntime::UtilityNetworkAttributeDataType& dataType);

ConfigureSubnetworkTrace::ConfigureSubnetworkTrace(QObject* parent /* = nullptr */):
  QObject(parent)
{
  m_utilityNetwork = new UtilityNetwork(m_featureLayerUrl, this);

  connect(m_utilityNetwork, &UtilityNetwork::doneLoading, this, &ConfigureSubnetworkTrace::onUtilityNetworkLoaded);

  connect(m_utilityNetwork, &UtilityNetwork::traceCompleted, this, &ConfigureSubnetworkTrace::onTraceCompleted);

  m_utilityNetwork->load();
}

QString expressionToString(UtilityTraceConditionalExpression* expression)
{
  switch (expression->traceConditionType())
  {
    case UtilityTraceConditionType::UtilityNetworkAttributeComparison:
    {
      const UtilityNetworkAttributeComparison* attributeExpression = static_cast<UtilityNetworkAttributeComparison*>(expression);
      const UtilityNetworkAttribute* networkAttribute = attributeExpression->networkAttribute();
      const UtilityNetworkAttribute* otherNetworkAttribute = attributeExpression->otherNetworkAttribute();
      const Domain networkDomain = networkAttribute->domain();
      const QString operatorAsString = comparisonOperatorToString(attributeExpression->comparisonOperator());

      // check if attribute domain is a coded value domain.
      if (!networkDomain.isEmpty() && (networkDomain.domainType() == DomainType::CodedValueDomain))
      {
        const CodedValueDomain codedValueDomain = static_cast<CodedValueDomain>(networkDomain);
        const QList<CodedValue> codedValues = codedValueDomain.codedValues();

        // get the coded value using the value as the index for the list of coded values
        const QString codedValueName = codedValues[attributeExpression->value().toInt()].name();

        return QString("`%1` %2 `%3`").arg(networkAttribute->name(), operatorAsString, codedValueName);
      }
      else
      {
        if (otherNetworkAttribute)
        {
          return QString("`%1` %2 `%3`").arg(networkAttribute->name(), operatorAsString, otherNetworkAttribute->name());
        }
        return QString("`%1` %2 `%3`").arg(networkAttribute->name(), operatorAsString, attributeExpression->value().toString());
      }
    }
    case UtilityTraceConditionType::UtilityCategoryComparison:
    {
      const UtilityCategoryComparison* comparisonExpression = static_cast<UtilityCategoryComparison*>(expression);

      return QString("`%1` %2").arg(comparisonExpression->category()->name(), (comparisonExpression->comparisonOperator() == UtilityCategoryComparisonOperator::Exists) ? "Exists" : "DoesNotExist");
    }
    case UtilityTraceConditionType::UtilityTraceAndCondition:
    {
      const UtilityTraceAndCondition* andExpression = static_cast<UtilityTraceAndCondition*>(expression);

      return QString("(%1) AND\n (%2)").arg(expressionToString(andExpression->leftExpression()), expressionToString(andExpression->rightExpression()));
    }
    case UtilityTraceConditionType::UtilityTraceOrCondition:
    {
      const UtilityTraceOrCondition* orExpression = static_cast<UtilityTraceOrCondition*>(expression);
      return QString("(%1) OR\n (%2)").arg(expressionToString(orExpression->leftExpression()), expressionToString(orExpression->rightExpression()));
    }
    default:
      return QString("Unknown trace conditional expression");
  }
}

QString comparisonOperatorToString(const UtilityAttributeComparisonOperator& comparisonOperator)
{
  switch (comparisonOperator)
  {
    case UtilityAttributeComparisonOperator::Equal:
      return QString("Equal");
    case UtilityAttributeComparisonOperator::NotEqual:
      return QString("NotEqual");
    case UtilityAttributeComparisonOperator::GreaterThan:
      return QString("GreaterThan");
    case UtilityAttributeComparisonOperator::GreaterThanEqual:
      return QString("GreaterThanEqual");
    case UtilityAttributeComparisonOperator::LessThan:
      return QString("LessThan");
    case UtilityAttributeComparisonOperator::LessThanEqual:
      return QString("LessThanEqual");
    case UtilityAttributeComparisonOperator::IncludesTheValues:
      return QString("IncludesTheValues");
    case UtilityAttributeComparisonOperator::DoesNotIncludeTheValues:
      return QString("DoesNotIncludeTheValues");
    case UtilityAttributeComparisonOperator::IncludesAny:
      return QString("IncludesAny");
    case UtilityAttributeComparisonOperator::DoesNotIncludeAny:
      return QString("DoesNotIncludeAny");
    default:
      return QString("Unknown comparison operator");
  }
}

QVariant convertToDataType(const QVariant& value, const Esri::ArcGISRuntime::UtilityNetworkAttributeDataType& dataType)
{
  switch (dataType)
  {
    case UtilityNetworkAttributeDataType::Integer:
    {
      return static_cast<int>(value.toDouble());
    }
    case UtilityNetworkAttributeDataType::Float:
    {
      return value.toFloat();
    }
    case UtilityNetworkAttributeDataType::Double:
    {
      return value.toDouble();
    }
    case UtilityNetworkAttributeDataType::Boolean:
    {
      return value.toBool();
    }
    default:
      return QVariant();
  }
}

void ConfigureSubnetworkTrace::codedValueOrInputText(const QString& currentText)
{
  // Update the UI to show the correct value entry for the attribute.
  if (m_networkDefinition)
  {
    const Domain domain = m_networkDefinition->networkAttribute(currentText)->domain();
    if (!domain.isEmpty() && (domain.domainType() == DomainType::CodedValueDomain))
    {
      m_valueSelectionListModel.clear();
      const CodedValueDomain codedValueDomain = static_cast<CodedValueDomain>(domain);

      for (CodedValue codedValue: codedValueDomain.codedValues())
        m_valueSelectionListModel.append(codedValue.name());

      m_textFieldVisible = false;
    }
    else
    {
      m_textFieldVisible = true;
    }
    emit valueSelectionListModelChanged();
    emit textFieldVisibleChanged();
  }
}

void ConfigureSubnetworkTrace::addCondition(const QString& selectedAttribute, int selectedOperator, const QVariant& selectedValue)
{
  // NOTE: You may also create a UtilityCategoryComparison with UtilityNetworkDefinition.Categories and UtilityCategoryComparisonOperator.

  UtilityNetworkAttribute* selectedNetworkAttribute = m_networkDefinition->networkAttribute(selectedAttribute);
  const QVariant convertedSelectedValue = convertToDataType(selectedValue, selectedNetworkAttribute->dataType());

  if (convertedSelectedValue.isNull())
  {
    m_dialogText = "Unknow network attribute data type";
    emit dialogTextChanged();
    emit showDialog();
    return;
  }

  const UtilityAttributeComparisonOperator selectedOperatorEnum = static_cast<UtilityAttributeComparisonOperator>(selectedOperator);

  // NOTE: You may also create a UtilityNetworkAttributeComparison with another NetworkAttribute.
  UtilityTraceConditionalExpression* expression = new UtilityNetworkAttributeComparison(selectedNetworkAttribute, selectedOperatorEnum, convertedSelectedValue, this);

  UtilityTraceConditionalExpression* otherExpression = static_cast<UtilityTraceConditionalExpression*>(m_traceConfiguration->traversability()->barriers());

  // NOTE: You may also combine expressions with UtilityTraceAndCondition
  UtilityTraceConditionalExpression* combineExpressions = new UtilityTraceOrCondition(otherExpression, expression, this);

  m_expressionBuilder = expressionToString(combineExpressions);
  emit expressionBuilderChanged();

  m_traceConfiguration->traversability()->setBarriers(combineExpressions);
}

void ConfigureSubnetworkTrace::changeIncludeBarriersState(bool includeBarriers)
{
  m_traceConfiguration->setIncludeBarriers(includeBarriers);
}

void ConfigureSubnetworkTrace::changeIncludeContainersState(bool includeContainers)
{
  m_traceConfiguration->setIncludeContainers(includeContainers);
}

void ConfigureSubnetworkTrace::reset()
{
  // Reset the barrier condition to the initial value.
  m_traceConfiguration->traversability()->setBarriers(m_initialExpression);
  m_expressionBuilder.clear();
  m_expressionBuilder = expressionToString(static_cast<UtilityTraceConditionalExpression*>(m_initialExpression));
  emit expressionBuilderChanged();
}

void ConfigureSubnetworkTrace::trace()
{
  if (!m_utilityNetwork || !m_utilityElementStartingLocation)
  {
    return;
  }

  m_busy = true;
  emit busyChanged();
  const QList<UtilityElement*> startingLocations {m_utilityElementStartingLocation};
  // Create utility trace parameters for the starting location.
  m_traceParams = new UtilityTraceParameters(UtilityTraceType::Subnetwork, startingLocations, this);
  m_traceParams->setTraceConfiguration(m_traceConfiguration);

  // trace the network
  m_utilityNetwork->trace(m_traceParams);
}

void ConfigureSubnetworkTrace::onTraceCompleted()
{
  if (m_utilityNetwork->traceResult()->isEmpty())
  {
    m_dialogText = "No results returned";
    emit dialogTextChanged();
    emit showDialog();
  }
  // Get the first result.
  UtilityTraceResult* result = m_utilityNetwork->traceResult()->at(0);

  const QList<UtilityElement*> elements = static_cast<UtilityElementTraceResult*>(result)->elements(this);

  // Display the number of elements found by the trace.
  m_dialogText = QString("%1 elements found.").arg(elements.length());
  m_busy = false;
  emit dialogTextChanged();
  emit showDialog();
  emit busyChanged();
}

void ConfigureSubnetworkTrace::onUtilityNetworkLoaded(const Error& e)
{
  if (!e.isEmpty())
  {
    m_dialogText = QString("%1 - %2").arg(e.message(), e.additionalMessage());
    m_busy = false;
    emit dialogTextChanged();
    emit showDialog();
    emit busyChanged();
    return;
  }

  m_busy = false;
  emit busyChanged();
  m_networkDefinition = m_utilityNetwork->definition();

  // Build the choice lists for network attribute comparison.
  for (UtilityNetworkAttribute* networkAttribute : m_networkDefinition->networkAttributes())
  {
    if (!networkAttribute->isSystemDefined())
      m_attributeListModel.append(networkAttribute->name());
  }
  emit attributeListModelChanged();

  // Create a default starting location.
  const UtilityNetworkSource* networkSource = m_networkDefinition->networkSource(m_deviceTableName);
  const UtilityAssetGroup* assetGroup = networkSource->assetGroup(m_assetGroupName);
  UtilityAssetType* assetType = assetGroup->assetType(m_assetTypeName);
  m_utilityElementStartingLocation = m_utilityNetwork->createElementWithAssetType(assetType, m_gloabId);

  QList<UtilityTerminal*> terminals = m_utilityElementStartingLocation->assetType()->terminalConfiguration()->terminals();

  // Set the terminal for this location. (For our case, we use the 'Load' terminal.)
  auto terminal = std::find_if(terminals.begin(), terminals.end(), [](UtilityTerminal* terminal)
  {
      return terminal->name() == "Load";
  });

  m_utilityElementStartingLocation->setTerminal(static_cast<UtilityTerminal*>(*terminal));

  // Get a default trace configuration from a tier to update the UI.
  const UtilityDomainNetwork* domainNetwork = m_networkDefinition->domainNetwork(m_domainNetworkName);
  const UtilityTier* utilityTierSource = domainNetwork->tier(m_tierName);

  // Set the trace configuration.
  m_traceConfiguration = utilityTierSource->traceConfiguration();

  m_initialExpression = m_traceConfiguration->traversability()->barriers();

  if (m_initialExpression)
  {
    m_expressionBuilder = expressionToString(static_cast<UtilityTraceConditionalExpression*>(m_initialExpression));
    emit expressionBuilderChanged();
  }

  // Set the traversability scope.
  utilityTierSource->traceConfiguration()->traversability()->setScope(UtilityTraversabilityScope::Junctions);
}

ConfigureSubnetworkTrace::~ConfigureSubnetworkTrace() = default;

void ConfigureSubnetworkTrace::init()
{
  qmlRegisterType<ConfigureSubnetworkTrace>("Esri.Samples", 1, 0, "ConfigureSubnetworkTraceSample");
}
<|endoftext|>


<commit_before>// Copyright (c) 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quic/test_tools/quic_test_backend.h"

#include <cstring>
#include <memory>

#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "quic/core/quic_buffer_allocator.h"
#include "quic/core/quic_simple_buffer_allocator.h"
#include "quic/core/web_transport_interface.h"
#include "quic/platform/api/quic_mem_slice.h"
#include "quic/tools/web_transport_test_visitors.h"

namespace quic {
namespace test {

QuicSimpleServerBackend::WebTransportResponse
QuicTestBackend::ProcessWebTransportRequest(
    const spdy::Http2HeaderBlock& request_headers,
    WebTransportSession* session) {
  if (!SupportsWebTransport()) {
    return QuicSimpleServerBackend::ProcessWebTransportRequest(request_headers,
                                                               session);
  }

  auto path_it = request_headers.find(":path");
  if (path_it == request_headers.end()) {
    WebTransportResponse response;
    response.response_headers[":status"] = "400";
    return response;
  }
  absl::string_view path = path_it->second;
  // Match any "/echo.*" pass, e.g. "/echo_foobar"
  if (absl::StartsWith(path, "/echo")) {
    WebTransportResponse response;
    response.response_headers[":status"] = "200";
    // Add response headers if the paramer has "set-header=XXX:YYY" query.
    GURL url = GURL(absl::StrCat("https://localhost", path));
    const std::vector<std::string>& params = absl::StrSplit(url.query(), '&');
    for (const auto& param : params) {
      absl::string_view param_view = param;
      if (absl::ConsumePrefix(&param_view, "set-header=")) {
        const std::vector<std::string_view> header_value =
            absl::StrSplit(param_view, ':');
        if (header_value.size() == 2 &&
            !absl::StartsWith(header_value[0], ":")) {
          response.response_headers[header_value[0]] = header_value[1];
        }
      }
    }

    response.visitor =
        std::make_unique<EchoWebTransportSessionVisitor>(session);
    return response;
  }

  WebTransportResponse response;
  response.response_headers[":status"] = "404";
  return response;
}

}  // namespace test
}  // namespace quic
<commit_msg>Disallow std::string_view in QUIC<commit_after>// Copyright (c) 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quic/test_tools/quic_test_backend.h"

#include <cstring>
#include <memory>

#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "quic/core/quic_buffer_allocator.h"
#include "quic/core/quic_simple_buffer_allocator.h"
#include "quic/core/web_transport_interface.h"
#include "quic/platform/api/quic_mem_slice.h"
#include "quic/tools/web_transport_test_visitors.h"

namespace quic {
namespace test {

QuicSimpleServerBackend::WebTransportResponse
QuicTestBackend::ProcessWebTransportRequest(
    const spdy::Http2HeaderBlock& request_headers,
    WebTransportSession* session) {
  if (!SupportsWebTransport()) {
    return QuicSimpleServerBackend::ProcessWebTransportRequest(request_headers,
                                                               session);
  }

  auto path_it = request_headers.find(":path");
  if (path_it == request_headers.end()) {
    WebTransportResponse response;
    response.response_headers[":status"] = "400";
    return response;
  }
  absl::string_view path = path_it->second;
  // Match any "/echo.*" pass, e.g. "/echo_foobar"
  if (absl::StartsWith(path, "/echo")) {
    WebTransportResponse response;
    response.response_headers[":status"] = "200";
    // Add response headers if the paramer has "set-header=XXX:YYY" query.
    GURL url = GURL(absl::StrCat("https://localhost", path));
    const std::vector<std::string>& params = absl::StrSplit(url.query(), '&');
    for (const auto& param : params) {
      absl::string_view param_view = param;
      if (absl::ConsumePrefix(&param_view, "set-header=")) {
        const std::vector<absl::string_view> header_value =
            absl::StrSplit(param_view, ':');
        if (header_value.size() == 2 &&
            !absl::StartsWith(header_value[0], ":")) {
          response.response_headers[header_value[0]] = header_value[1];
        }
      }
    }

    response.visitor =
        std::make_unique<EchoWebTransportSessionVisitor>(session);
    return response;
  }

  WebTransportResponse response;
  response.response_headers[":status"] = "404";
  return response;
}

}  // namespace test
}  // namespace quic
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: global.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: vg $ $Date: 2007-09-20 15:03:42 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _OSL_PROCESS_H_
#include <osl/process.h>
#endif
#ifndef _RTL_OSTRINGBUFFER_HXX_
#include <rtl/strbuf.hxx>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef     _OSL_THREAD_H_
#include    <osl/thread.h>
#endif
#ifndef     _OSL_FILE_HXX_
#include    <osl/file.hxx>
#endif

#include <stdlib.h>
#include <stdio.h>
#if defined(SAL_W32) || defined(SAL_OS2)
#include <io.h>
#include <direct.h>
#include <errno.h>
#endif

#ifdef UNX
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#endif

#ifndef _CODEMAKER_GLOBAL_HXX_
#include    <codemaker/global.hxx>
#endif

#ifdef SAL_UNX
#define SEPARATOR '/'
#else
#define SEPARATOR '\\'
#endif

using namespace ::rtl;
using namespace ::osl;

OString createFileNameFromType( const OString& destination,
                                const OString typeName,
                                const OString postfix,
                                sal_Bool bLowerCase,
                                const OString prefix )
{
    OString type(typeName);

    if (bLowerCase)
    {
        type = typeName.toAsciiLowerCase();
    }

    sal_uInt32 length = destination.getLength();

    sal_Bool withPoint = sal_False;
    if (length == 0)
    {
        length++;
        withPoint = sal_True;
    }

    length += prefix.getLength() + type.getLength() + postfix.getLength();

    sal_Bool withSeperator = sal_False;
    if (destination.getStr()[destination.getLength()] != '\\' &&
        destination.getStr()[destination.getLength()] != '/' &&
        type.getStr()[0] != '\\' &&
        type.getStr()[0] != '/')
    {
        length++;
        withSeperator = sal_True;
    }

    OStringBuffer nameBuffer(length);

    if (withPoint)
        nameBuffer.append('.');
    else
        nameBuffer.append(destination.getStr(), destination.getLength());

    if (withSeperator)
        nameBuffer.append("/", 1);

    OString tmpStr(type);
    if (prefix.getLength() > 0)
    {
        tmpStr = type.replaceAt(type.lastIndexOf('/')+1, 0, prefix);
    }

    nameBuffer.append(tmpStr.getStr(), tmpStr.getLength());
    nameBuffer.append(postfix.getStr(), postfix.getLength());

    OString fileName(nameBuffer);

    sal_Char token;
#ifdef SAL_UNX
    fileName = fileName.replace('\\', '/');
    token = '/';
#else
    fileName = fileName.replace('/', '\\');
    token = '\\';
#endif

    nameBuffer = OStringBuffer(length);

    sal_Int32 nIndex = 0;
    do
    {
        nameBuffer.append(fileName.getToken( 0, token, nIndex ).getStr());

        if (nameBuffer.getLength() == 0 || OString(".") == nameBuffer.getStr())
        {
            nameBuffer.append(token);
            continue;
        }

#if defined(SAL_UNX) || defined(SAL_OS2)
        if (mkdir((char*)nameBuffer.getStr(), 0777) == -1)
#else
           if (mkdir((char*)nameBuffer.getStr()) == -1)
#endif
        {
            if ( errno == ENOENT )
                return OString();
        }

        nameBuffer.append(token);
    }
    while ( nIndex >= 0 );

    return fileName;
}

sal_Bool fileExists(const OString& fileName)
{
    FILE  *f= fopen(fileName.getStr(), "r");

    if (f != NULL)
    {
        fclose(f);
        return sal_True;
    }

    return sal_False;
}

sal_Bool checkFileContent(const OString& targetFileName, const OString& tmpFileName)
{
    FILE  *target = fopen(targetFileName.getStr(), "r");
    FILE  *tmp = fopen(tmpFileName.getStr(), "r");
    sal_Bool ret = sal_False;

    if (target != NULL && tmp != NULL)
    {
        sal_Bool    bFindChanges = sal_False;
        sal_Char    buffer1[1024+1];
        sal_Char    buffer2[1024+1];
        sal_Int32   n1 = 0;
        sal_Int32   n2 = 0;

        while ( !bFindChanges && !feof(target) && !feof(tmp))
        {
            n1 = fread(buffer1, sizeof(sal_Char), 1024, target);
            n2 = fread(buffer2, sizeof(sal_Char), 1024, tmp);

            if ( n1 != n2 )
            {
                bFindChanges = sal_True;
            }
            else
            {
                if ( rtl_compareMemory(buffer1, buffer2, n2) != 0 )
                    bFindChanges =  sal_True;
            }
        }

        fclose(target);
        fclose(tmp);

        if ( bFindChanges )
        {
            if ( !unlink(targetFileName.getStr()) )
                if ( !rename(tmpFileName.getStr(), targetFileName.getStr()) )
                    ret = sal_True;
        }
        else
        {
            if ( !unlink(tmpFileName.getStr()) )
                ret = sal_True;
        }
    }

    return ret;
}

const OString inGlobalSet(const OUString & rValue)
{
    OString sValue( OUStringToOString(rValue, RTL_TEXTENCODING_UTF8) );
    static StringSet aGlobalMap;
    StringSet::iterator iter = aGlobalMap.find( sValue );
    if( iter != aGlobalMap.end() )
        return *iter;
    return *(aGlobalMap.insert( sValue ).first);
}

static sal_Bool isFileUrl(const OString& fileName)
{
    if (fileName.indexOf("file://") == 0 )
        return sal_True;
    return sal_False;
}

OUString convertToFileUrl(const OString& fileName)
{
    if ( isFileUrl(fileName) )
    {
        return OStringToOUString(fileName, osl_getThreadTextEncoding());
    }

    OUString uUrlFileName;
    OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
    if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
    {
        OUString uWorkingDir;
        if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) {
            OSL_ASSERT(false);
        }
        if (FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
    } else
    {
        if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
    }

    return uUrlFileName;
}

//*************************************************************************
// FileStream
//*************************************************************************
FileStream::FileStream()
{
}

FileStream::FileStream(const OString& name, FileAccessMode mode)
    : m_pFile(NULL)
{
    if ( name.getLength() > 0 )
    {
        m_name = name;
        m_pFile = fopen(m_name, checkAccessMode(mode));
    }
}

FileStream::~FileStream()
{
    if ( isValid() )
    {
        fflush(m_pFile);
        fclose(m_pFile);
    }
}

sal_Bool FileStream::isValid()
{
    if ( m_pFile )
        return sal_True;

    return sal_False;
}

void FileStream::open(const OString& name, FileAccessMode mode)
{
    if ( name.getLength() > 0 )
    {
        m_name = name;
        m_pFile = fopen(m_name, checkAccessMode(mode));
    }
}

void FileStream::close()
{
    if ( isValid() )
    {
        fflush(m_pFile);
        fclose(m_pFile);
        m_pFile = NULL;
        m_name = OString();
    }
}

sal_Int32 FileStream::getSize()
{
    sal_Int32 pos = 0;
    sal_Int32 size = 0;
    if ( isValid() )
    {
        fflush(m_pFile);
        pos = ftell(m_pFile);
        if (!fseek(m_pFile, 0, SEEK_END))
            size = ftell(m_pFile);
        fseek(m_pFile, pos, SEEK_SET);
    }
    return size;
}

const sal_Char* FileStream::checkAccessMode(FileAccessMode mode)
{
    switch( mode )
    {
    case FAM_READ:
        return "r";
    case FAM_WRITE:
        return "w";
    case FAM_APPEND:
        return "a";
    case FAM_READWRITE_EXIST:
        return "r+";
    case FAM_READWRITE:
        return "w+";
    case FAM_READAPPEND:
        return "a+";
    }
    return "w+";
}

<commit_msg>INTEGRATION: CWS changefileheader (1.13.12); FILE MERGED 2008/04/01 15:22:57 thb 1.13.12.3: #i85898# Stripping all external header guards 2008/04/01 12:32:32 thb 1.13.12.2: #i85898# Stripping all external header guards 2008/03/31 07:25:06 rt 1.13.12.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: global.cxx,v $
 * $Revision: 1.14 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#include <osl/process.h>
#ifndef _RTL_OSTRINGBUFFER_HXX_
#include <rtl/strbuf.hxx>
#endif
#include <rtl/ustring.hxx>
#include    <osl/thread.h>
#include    <osl/file.hxx>

#include <stdlib.h>
#include <stdio.h>
#if defined(SAL_W32) || defined(SAL_OS2)
#include <io.h>
#include <direct.h>
#include <errno.h>
#endif

#ifdef UNX
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#endif
#include    <codemaker/global.hxx>

#ifdef SAL_UNX
#define SEPARATOR '/'
#else
#define SEPARATOR '\\'
#endif

using namespace ::rtl;
using namespace ::osl;

OString createFileNameFromType( const OString& destination,
                                const OString typeName,
                                const OString postfix,
                                sal_Bool bLowerCase,
                                const OString prefix )
{
    OString type(typeName);

    if (bLowerCase)
    {
        type = typeName.toAsciiLowerCase();
    }

    sal_uInt32 length = destination.getLength();

    sal_Bool withPoint = sal_False;
    if (length == 0)
    {
        length++;
        withPoint = sal_True;
    }

    length += prefix.getLength() + type.getLength() + postfix.getLength();

    sal_Bool withSeperator = sal_False;
    if (destination.getStr()[destination.getLength()] != '\\' &&
        destination.getStr()[destination.getLength()] != '/' &&
        type.getStr()[0] != '\\' &&
        type.getStr()[0] != '/')
    {
        length++;
        withSeperator = sal_True;
    }

    OStringBuffer nameBuffer(length);

    if (withPoint)
        nameBuffer.append('.');
    else
        nameBuffer.append(destination.getStr(), destination.getLength());

    if (withSeperator)
        nameBuffer.append("/", 1);

    OString tmpStr(type);
    if (prefix.getLength() > 0)
    {
        tmpStr = type.replaceAt(type.lastIndexOf('/')+1, 0, prefix);
    }

    nameBuffer.append(tmpStr.getStr(), tmpStr.getLength());
    nameBuffer.append(postfix.getStr(), postfix.getLength());

    OString fileName(nameBuffer);

    sal_Char token;
#ifdef SAL_UNX
    fileName = fileName.replace('\\', '/');
    token = '/';
#else
    fileName = fileName.replace('/', '\\');
    token = '\\';
#endif

    nameBuffer = OStringBuffer(length);

    sal_Int32 nIndex = 0;
    do
    {
        nameBuffer.append(fileName.getToken( 0, token, nIndex ).getStr());

        if (nameBuffer.getLength() == 0 || OString(".") == nameBuffer.getStr())
        {
            nameBuffer.append(token);
            continue;
        }

#if defined(SAL_UNX) || defined(SAL_OS2)
        if (mkdir((char*)nameBuffer.getStr(), 0777) == -1)
#else
           if (mkdir((char*)nameBuffer.getStr()) == -1)
#endif
        {
            if ( errno == ENOENT )
                return OString();
        }

        nameBuffer.append(token);
    }
    while ( nIndex >= 0 );

    return fileName;
}

sal_Bool fileExists(const OString& fileName)
{
    FILE  *f= fopen(fileName.getStr(), "r");

    if (f != NULL)
    {
        fclose(f);
        return sal_True;
    }

    return sal_False;
}

sal_Bool checkFileContent(const OString& targetFileName, const OString& tmpFileName)
{
    FILE  *target = fopen(targetFileName.getStr(), "r");
    FILE  *tmp = fopen(tmpFileName.getStr(), "r");
    sal_Bool ret = sal_False;

    if (target != NULL && tmp != NULL)
    {
        sal_Bool    bFindChanges = sal_False;
        sal_Char    buffer1[1024+1];
        sal_Char    buffer2[1024+1];
        sal_Int32   n1 = 0;
        sal_Int32   n2 = 0;

        while ( !bFindChanges && !feof(target) && !feof(tmp))
        {
            n1 = fread(buffer1, sizeof(sal_Char), 1024, target);
            n2 = fread(buffer2, sizeof(sal_Char), 1024, tmp);

            if ( n1 != n2 )
            {
                bFindChanges = sal_True;
            }
            else
            {
                if ( rtl_compareMemory(buffer1, buffer2, n2) != 0 )
                    bFindChanges =  sal_True;
            }
        }

        fclose(target);
        fclose(tmp);

        if ( bFindChanges )
        {
            if ( !unlink(targetFileName.getStr()) )
                if ( !rename(tmpFileName.getStr(), targetFileName.getStr()) )
                    ret = sal_True;
        }
        else
        {
            if ( !unlink(tmpFileName.getStr()) )
                ret = sal_True;
        }
    }

    return ret;
}

const OString inGlobalSet(const OUString & rValue)
{
    OString sValue( OUStringToOString(rValue, RTL_TEXTENCODING_UTF8) );
    static StringSet aGlobalMap;
    StringSet::iterator iter = aGlobalMap.find( sValue );
    if( iter != aGlobalMap.end() )
        return *iter;
    return *(aGlobalMap.insert( sValue ).first);
}

static sal_Bool isFileUrl(const OString& fileName)
{
    if (fileName.indexOf("file://") == 0 )
        return sal_True;
    return sal_False;
}

OUString convertToFileUrl(const OString& fileName)
{
    if ( isFileUrl(fileName) )
    {
        return OStringToOUString(fileName, osl_getThreadTextEncoding());
    }

    OUString uUrlFileName;
    OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
    if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
    {
        OUString uWorkingDir;
        if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) {
            OSL_ASSERT(false);
        }
        if (FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
    } else
    {
        if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
    }

    return uUrlFileName;
}

//*************************************************************************
// FileStream
//*************************************************************************
FileStream::FileStream()
{
}

FileStream::FileStream(const OString& name, FileAccessMode mode)
    : m_pFile(NULL)
{
    if ( name.getLength() > 0 )
    {
        m_name = name;
        m_pFile = fopen(m_name, checkAccessMode(mode));
    }
}

FileStream::~FileStream()
{
    if ( isValid() )
    {
        fflush(m_pFile);
        fclose(m_pFile);
    }
}

sal_Bool FileStream::isValid()
{
    if ( m_pFile )
        return sal_True;

    return sal_False;
}

void FileStream::open(const OString& name, FileAccessMode mode)
{
    if ( name.getLength() > 0 )
    {
        m_name = name;
        m_pFile = fopen(m_name, checkAccessMode(mode));
    }
}

void FileStream::close()
{
    if ( isValid() )
    {
        fflush(m_pFile);
        fclose(m_pFile);
        m_pFile = NULL;
        m_name = OString();
    }
}

sal_Int32 FileStream::getSize()
{
    sal_Int32 pos = 0;
    sal_Int32 size = 0;
    if ( isValid() )
    {
        fflush(m_pFile);
        pos = ftell(m_pFile);
        if (!fseek(m_pFile, 0, SEEK_END))
            size = ftell(m_pFile);
        fseek(m_pFile, pos, SEEK_SET);
    }
    return size;
}

const sal_Char* FileStream::checkAccessMode(FileAccessMode mode)
{
    switch( mode )
    {
    case FAM_READ:
        return "r";
    case FAM_WRITE:
        return "w";
    case FAM_APPEND:
        return "a";
    case FAM_READWRITE_EXIST:
        return "r+";
    case FAM_READWRITE:
        return "w+";
    case FAM_READAPPEND:
        return "a+";
    }
    return "w+";
}

<|endoftext|>


<commit_before>#include "Global.h"

#include <vector>
#include <iostream>
#include <thread>
#include <unordered_map>
#include <cmath>
#include <chrono>

#include "Controller.h"
#include "Job.h"
#include "JobHandler.h"
#include "Sensor.h"

#include "Controller/UDPClientController.h"
#include "Controller/FakeMotorController.h"
#include "Controller/MotorController.h"
#include "JobHandler/ManualInputsHandler.h"
#include "JobHandler/ForwardHandler.h"
#include "JobHandler/R2Server.h"
#include "JobHandler/SafetyHandler.h"
#include "Sensor/UDPServerSensor.h"
#include "Sensor/UltrasoundSensor.h"

/** Initializes sensors */
smap<ptr<Sensor>> initializeSensors(smap<string>& args) {
	printf("Initialize sensors\n");

	smap<ptr<Sensor>> sensors;
	if (args.find("udp-server-ip") != args.end() && args.find("udp-server-port") != args.end()) {
		sensors["UDP SERVER"] = std::make_shared<UDPServerSensor>(args["udp-server-ip"], atoi(args["udp-server-port"].c_str()));
	}
	else {
		sensors["UDP SERVER"] = std::make_shared<UDPServerSensor>("0.0.0.0", 9000);
	}

	if (args.find("ultrasound-com-port") != args.end()) {
		sensors["ULTRASOUND"] = std::make_shared<UltrasoundSensor>(args["ultrasound-com-port"], B9600);
	}
	else {
		std::cout << "No ultrasound port specified." << std::endl;
	}

	return sensors;
}

/** Initializes controllers */
smap<ptr<Controller>> initializeControllers(smap<string>& args) {
	printf("Initialize controllers\n");

	smap<ptr<Controller>> controllers;
	if (args.find("udp-nuc-ip") != args.end() && args.find("udp-nuc-port") != args.end()) {
		controllers["UDP NUC"] = std::make_shared<UDPClientController>(args["udp-nuc-ip"], atoi(args["udp-nuc-port"].c_str()));
	}
	else {
		std::cout << "No UDP NUC ip or port specified." << std::endl;
	}

	if (args.find("motor-com-port") != args.end()) {
		controllers["MOTOR"] = std::make_shared<MotorController>(args["motor-com-port"], B9600);
	}
	else if (args.find("use-fake-motor") != args.end()) {
		controllers["MOTOR"] = std::make_shared<FakeMotorController>();
	}
	else {
		std::cout << "No motor port specified." << std::endl;
	}

	return controllers;
}

/** Initialize a list of jobs */
deque<Job> initializeJobs(smap<string>& args) {
	printf("Initialize jobs\n");

	deque<Job> jobs;
	jobs.push_back(Job("manual-inputs"));
	return jobs;
}

/** Initialize background jobs */
deque<JobHandler> initializeBackgroundJobs(smap<string>& args, smap<ptr<Sensor>>& sensors, smap<ptr<Controller>>& controllers) {
	printf("Initializing background jobs\n");

	deque<JobHandler> jobs;
	if (args.find("disable-safety") != args.end()) {
		printf("WARNING: DISABLING MOTOR SAFETY\n");
	}
	else {
		jobs.push_back(SafetyHandler());
	}

	smap<ptr<Controller>> routes;
	if (controllers.find("UDP NUC") != controllers.end()) {
		routes["PICAMERA"] = controllers["UDP NUC"];
	}
	jobs.push_back(ForwardHandler(routes));
	return jobs;
}

int main(int argc, char *argv[]) {
	smap<string> args = parseArguments(argc, argv);
	/** Initialization */
	smap<ptr<Sensor>> sensors = initializeSensors(args);
	smap<ptr<Controller>> controllers = initializeControllers(args);
	deque<Job> jobQueue = initializeJobs(args);
	ptr<JobHandler> currentJob;
	deque<JobHandler> bgJobs = initializeBackgroundJobs(args, sensors, controllers);

	//TODO: method arg should be sql command stored in a char

	/** Main execution loop */
	while (1) {
		// Collect data from sensors
		printf("Collecting data from sensors\n");
		SensorData data;
		for (auto itr : sensors) {
			ptr<Sensor> sensor = itr.second;
			sensor->fillData(data);
		}

		// Get the next job in the queue
		if (!currentJob) {
			if (jobQueue.size() > 0) {
				Job nextJob = jobQueue.front();
				jobQueue.pop_front();
				currentJob = JobHandler::GetJobHandler(nextJob.getHandler());
			}
		}

		// Run the current job
		printf("Executing the current job\n");
		ControllerData outputs;
		if (currentJob) {
			currentJob->execute(jobQueue, data, outputs);
		}

		// Run background jobs
		printf("Executing background jobs\n");
		for (auto itr : bgJobs) {
			itr.execute(jobQueue, data, outputs);
		}

		// Send output data to controllers
		printf("Sending outputs to controllers\n");
		for (auto itr : controllers) {
			ptr<Controller> controller = itr.second;
			std::cout << controller->getName() << std::endl;
			controller->sendData(outputs);
		}

		// Sleep
		Sleep(20);
	}
}
<commit_msg>Make outputs more clear<commit_after>#include "Global.h"

#include <vector>
#include <iostream>
#include <thread>
#include <unordered_map>
#include <cmath>
#include <chrono>

#include "Controller.h"
#include "Job.h"
#include "JobHandler.h"
#include "Sensor.h"

#include "Controller/UDPClientController.h"
#include "Controller/FakeMotorController.h"
#include "Controller/MotorController.h"
#include "JobHandler/ManualInputsHandler.h"
#include "JobHandler/ForwardHandler.h"
#include "JobHandler/R2Server.h"
#include "JobHandler/SafetyHandler.h"
#include "Sensor/UDPServerSensor.h"
#include "Sensor/UltrasoundSensor.h"

/** Initializes sensors */
smap<ptr<Sensor>> initializeSensors(smap<string>& args) {
	printf("*** Initialize sensors\n");

	smap<ptr<Sensor>> sensors;
	if (args.find("udp-server-ip") != args.end() && args.find("udp-server-port") != args.end()) {
		sensors["UDP SERVER"] = std::make_shared<UDPServerSensor>(args["udp-server-ip"], atoi(args["udp-server-port"].c_str()));
	}
	else {
		sensors["UDP SERVER"] = std::make_shared<UDPServerSensor>("0.0.0.0", 9000);
	}

	if (args.find("ultrasound-com-port") != args.end()) {
		sensors["ULTRASOUND"] = std::make_shared<UltrasoundSensor>(args["ultrasound-com-port"], B9600);
	}
	else {
		std::cout << "No ultrasound port specified." << std::endl;
	}

	return sensors;
}

/** Initializes controllers */
smap<ptr<Controller>> initializeControllers(smap<string>& args) {
	printf("*** Initialize controllers\n");

	smap<ptr<Controller>> controllers;
	if (args.find("udp-nuc-ip") != args.end() && args.find("udp-nuc-port") != args.end()) {
		controllers["UDP NUC"] = std::make_shared<UDPClientController>(args["udp-nuc-ip"], atoi(args["udp-nuc-port"].c_str()));
	}
	else {
		std::cout << "No UDP NUC ip or port specified." << std::endl;
	}

	if (args.find("motor-com-port") != args.end()) {
		controllers["MOTOR"] = std::make_shared<MotorController>(args["motor-com-port"], B9600);
	}
	else if (args.find("use-fake-motor") != args.end()) {
		controllers["MOTOR"] = std::make_shared<FakeMotorController>();
	}
	else {
		std::cout << "No motor port specified." << std::endl;
	}

	return controllers;
}

/** Initialize a list of jobs */
deque<Job> initializeJobs(smap<string>& args) {
	printf("*** Initialize jobs\n");

	deque<Job> jobs;
	jobs.push_back(Job("manual-inputs"));
	return jobs;
}

/** Initialize background jobs */
deque<JobHandler> initializeBackgroundJobs(smap<string>& args, smap<ptr<Sensor>>& sensors, smap<ptr<Controller>>& controllers) {
	printf("*** Initializing background jobs\n");

	deque<JobHandler> jobs;
	if (args.find("disable-safety") != args.end()) {
		printf("WARNING: DISABLING MOTOR SAFETY\n");
	}
	else {
		jobs.push_back(SafetyHandler());
	}

	smap<ptr<Controller>> routes;
	if (controllers.find("UDP NUC") != controllers.end()) {
		routes["PICAMERA"] = controllers["UDP NUC"];
	}
	jobs.push_back(ForwardHandler(routes));
	return jobs;
}

int main(int argc, char *argv[]) {
	smap<string> args = parseArguments(argc, argv);
	/** Initialization */
	smap<ptr<Sensor>> sensors = initializeSensors(args);
	smap<ptr<Controller>> controllers = initializeControllers(args);
	deque<Job> jobQueue = initializeJobs(args);
	ptr<JobHandler> currentJob;
	deque<JobHandler> bgJobs = initializeBackgroundJobs(args, sensors, controllers);

	//TODO: method arg should be sql command stored in a char

	/** Main execution loop */
	while (1) {
		// Collect data from sensors
		printf("** Collecting data from sensors\n");
		SensorData data;
		for (auto itr : sensors) {
			ptr<Sensor> sensor = itr.second;
			sensor->fillData(data);
		}

		// Get the next job in the queue
		if (!currentJob) {
			if (jobQueue.size() > 0) {
				Job nextJob = jobQueue.front();
				jobQueue.pop_front();
				currentJob = JobHandler::GetJobHandler(nextJob.getHandler());
			}
		}

		// Run the current job
		ControllerData outputs;
		if (currentJob) {
			printf("** Executing the current job\n");
			currentJob->execute(jobQueue, data, outputs);
		}
		else {
			printf("** No current job to execute\n");
		}

		// Run background jobs
		printf("** Executing background jobs\n");
		for (auto itr : bgJobs) {
			itr.execute(jobQueue, data, outputs);
		}

		// Send output data to controllers
		printf("** Sending outputs to controllers\n");
		for (auto itr : controllers) {
			ptr<Controller> controller = itr.second;
			std::cout << controller->getName() << std::endl;
			controller->sendData(outputs);
		}

		// Sleep
		Sleep(20);
	}
}
<|endoftext|>