<commit_before>/// \file BitcodeParser.cpp

#include "chi/BitcodeParser.hpp"
#include "chi/LLVMVersion.hpp"
#include "chi/Support/Result.hpp"

#if LLVM_VERSION_LESS_EQUAL(3, 9)
#include <llvm/Bitcode/ReaderWriter.h>
#else
#include <llvm/Bitcode/BitcodeReader.h>
#endif

#include <llvm/Support/MemoryBuffer.h>

namespace chi {

namespace {

    template<typename MemBuffType>
	Result parseBitcodeMemBuff(MemBuffType buff, llvm::LLVMContext& ctx, std::unique_ptr<llvm::Module>* toFill) {

		assert(toFill != nullptr && "Cannot pass a null toFill pointer to parseBitcodeMemBuff");

		Result res;

		auto errorOrMod = llvm::parseBitcodeFile(buff, ctx);
		if (!errorOrMod) {
			std::vector<std::string> errorMsgs;

#if LLVM_VERSION_AT_LEAST(4, 0)
			auto E = errorOrMod.takeError();

			llvm::handleAllErrors(
			    std::move(E), [&errorMsgs](llvm::ErrorInfoBase& err) { errorMsgs.push_back(err.message()); });
#endif

			res.addEntry("EUKN", "Failed to parse generated bitcode.",
			             {{"Error Messages", errorMsgs}});

			return res;
		}
		*toFill =
#if LLVM_VERSION_LESS_EQUAL(3, 6)
		    std::unique_ptr<llvm::Module>
#else
		    std::move
#endif
		    (errorOrMod.get());

		return res;
	}

} // namespace

	Result parseBitcodeFile(const boost::filesystem::path& file, llvm::LLVMContext& ctx, std::unique_ptr<llvm::Module>* toFill) {

		Result res;

		// if all of this is true, then we can read the cache
		auto bcFileBufferOrError = llvm::MemoryBuffer::getFile(file.string());
		if (!bcFileBufferOrError) {
			res.addEntry("EUKN", "Failed to load LLVM module from disk", {{"File", file.string()}});
			return res;
		}

		return parseBitcodeMemBuff(bcFileBufferOrError.get()
#if LLVM_VERSION_AT_LEAST(3, 6)
          ->getMemBufferRef()
#else
      .get()
#endif
        , ctx, toFill);
	}
	Result parseBitcodeString(const std::string& bitcode, llvm::LLVMContext& ctx, std::unique_ptr<llvm::Module>* toFill) {

		return parseBitcodeMemBuff(
	#if LLVM_VERSION_LESS_EQUAL(3, 5)
				llvm::MemoryBuffer::getMemBufferCopy
	#else
				llvm::MemoryBufferRef
	#endif
				(bitcode, "generated.bc"), ctx, toFill);

	}

} // namespace chi

<commit_msg>Add missing include<commit_after>/// \file BitcodeParser.cpp

#include "chi/BitcodeParser.hpp"
#include "chi/LLVMVersion.hpp"
#include "chi/Support/Result.hpp"

#if LLVM_VERSION_LESS_EQUAL(3, 9)
#include <llvm/Bitcode/ReaderWriter.h>
#else
#include <llvm/Bitcode/BitcodeReader.h>
#endif

#include <llvm/Support/MemoryBuffer.h>
#include <llvm/IR/Module.h>

namespace chi {

namespace {

    template<typename MemBuffType>
	Result parseBitcodeMemBuff(MemBuffType buff, llvm::LLVMContext& ctx, std::unique_ptr<llvm::Module>* toFill) {

		assert(toFill != nullptr && "Cannot pass a null toFill pointer to parseBitcodeMemBuff");

		Result res;

		auto errorOrMod = llvm::parseBitcodeFile(buff, ctx);
		if (!errorOrMod) {
			std::vector<std::string> errorMsgs;

#if LLVM_VERSION_AT_LEAST(4, 0)
			auto E = errorOrMod.takeError();

			llvm::handleAllErrors(
			    std::move(E), [&errorMsgs](llvm::ErrorInfoBase& err) { errorMsgs.push_back(err.message()); });
#endif

			res.addEntry("EUKN", "Failed to parse generated bitcode.",
			             {{"Error Messages", errorMsgs}});

			return res;
		}
		*toFill =
#if LLVM_VERSION_LESS_EQUAL(3, 6)
		    std::unique_ptr<llvm::Module>
#else
		    std::move
#endif
		    (errorOrMod.get());

		return res;
	}

} // namespace

	Result parseBitcodeFile(const boost::filesystem::path& file, llvm::LLVMContext& ctx, std::unique_ptr<llvm::Module>* toFill) {

		Result res;

		// if all of this is true, then we can read the cache
		auto bcFileBufferOrError = llvm::MemoryBuffer::getFile(file.string());
		if (!bcFileBufferOrError) {
			res.addEntry("EUKN", "Failed to load LLVM module from disk", {{"File", file.string()}});
			return res;
		}

		return parseBitcodeMemBuff(bcFileBufferOrError.get()
#if LLVM_VERSION_AT_LEAST(3, 6)
          ->getMemBufferRef()
#else
      .get()
#endif
        , ctx, toFill);
	}
	Result parseBitcodeString(const std::string& bitcode, llvm::LLVMContext& ctx, std::unique_ptr<llvm::Module>* toFill) {

		return parseBitcodeMemBuff(
	#if LLVM_VERSION_LESS_EQUAL(3, 5)
				llvm::MemoryBuffer::getMemBufferCopy
	#else
				llvm::MemoryBufferRef
	#endif
				(bitcode, "generated.bc"), ctx, toFill);

	}

} // namespace chi

<|endoftext|>


<commit_before>/** \copyright
 * Copyright (c) 2013, Balazs Racz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file Dispatcher.hxx
 *
 * Class for dispatching incoming messages to handlers.
 *
 * @author Balazs Racz
 * @date 2 Dec 2013
 */

#ifndef _executor_Dispatcher_hxx_
#define _executor_Dispatcher_hxx_

#include <vector>

#include "executor/notifiable.hxx"
#include "executor/allocator.hxx"
#include "executor/control_flow.hxx"
#include "nmranet/NMRAnetIf.hxx"
#include "nmranet/NMRAnetNode.hxx"

/**
   Abstract class for handling an incoming message of a specifc MTI in NMRAnet.
   Handle calls are always made on the IF's read executor.

   There are two allocation mechanism available:

   . in one case the handler is directly able to process messages and performs
   the allocation itself. This is helpful for synchronous handlers, or when
   actual objects (instead of factories) are performing the handling of
   messages, such as when waiting for responses to outbound messages.

   . or the handler call actually returns an Allocator, which the caller has to
   acquire a handler from and re-post the same call to that handler.
 */
class HandlerBase : public QueueMember
{
public:
    /** Retrieves the allocator needed for a handler. The caller must retrieve
     * an instance from the allocator, or if the returned allocator is NULL,
     * then the caller may invoke this->handle_message immediately.
     *
     * @returns an allocator of type HandlerBase; or NULL.
     */
    virtual AllocatorBase* get_allocator()
    {
        return NULL;
    }
};

template <class Param> class ParamHandler : public HandlerBase
{
public:
    /**
     * Initiates handling of an incoming message.
     *
     * @param message is the incoming message. Does not take ownership.
     * @param done notifiable, will be notified when the message handling is
     * completed and message can be deallocated. Required.
     */
    virtual void handle_message(Param* message, Notifiable* done) = 0;
};

/**
   This class takes registered handlers for incoming messages. When a message
   shows up, all the handlers that match that message will be invoked. When all
   the handlers return, the message will be marked as completed, and the
   current flow will be released for further message calls.

   Handlers are called in no particular order.

   Allocation semantics:

   This flow is attached to a TypedAllocator owned by the If. The flow will
   return itself to the allocator automatically.
 */
template <typename ID> class DispatchFlow : public ControlFlow
{
public:
    DispatchFlow(Executor* executor);
    virtual ~DispatchFlow();
    /**
       Handles an incoming message. Prior to this call the parameters needed
       for the call should be injected into the flow using an
       implementation-specific method.

       @param id is the identifier of the incoming message.

       The flow *this will release itself to the allocator when the message
       handling is done.
     */
    void IncomingMessage(ID id);

    TypedAllocator<DispatchFlow<ID>>* allocator()
    {
        return &allocator_;
    }

    size_t handler_count()
    {
        size_t size = handlers_.size();
        if (pending_delete_index_ < 0) return size;
        for (int i = pending_delete_index_; i < (int)handlers_.size(); ++i) {
            if (handlers_[i].handler == nullptr) --size;
        }
        return size;
    }

protected:
    /**
       Adds a new handler to this dispatcher.

       A handler will be called if incoming_mti & mask == mti & mask.

       @param mti is the identifier of the message to listen to.
       @param mask is the mask of the mti matcher.
       @param handler is the MTI handler. It must stay alive so long as this If
       is alive.
     */
    void RegisterHandler(ID id, ID mask, HandlerBase* handler);

    //! Removes a specific instance of a handler from this IF.
    void UnregisterHandler(ID id, ID mask, HandlerBase* handler);

    /**
       Makes an implementation-specific call to the actual
       handler. Implementations will need to take certain handler arguments from
       member variables. The 'done' notifiable must be called in all cases.
     */
    virtual void CallCurrentHandler(HandlerBase* handler, Notifiable* done) = 0;

    /**
       This function will be called when the flow and all children are
       done. Useful for implementations to release memory and buffers
       associated with the current parameters.

       @returns true if the flow instance should be returned to the
       allocator. If returns false, must take care of changing the flow to a
       different state.
     */
    virtual bool OnFlowFinished()
    {
        return true;
    };

    virtual void CheckNotStartedState() {
        HASSERT(IsNotStarted());
    }

private:
    // State handler. Calls the current handler.
    ControlFlowAction HandleCall();
    // State handler. If calling the handler didn't work, this state will be
    // called after the allocation.
    ControlFlowAction HandleAllocateResult();
    // State handler. Waits for the children to finish.
    ControlFlowAction HandleWaitForChildren();

    struct HandlerInfo
    {
        HandlerInfo() : handler(nullptr)
        {
        }
        ID id;
        ID mask;
        // NULL if the handler has been removed.
        HandlerBase* handler;

        bool Equals(ID id, ID mask, HandlerBase* handler)
        {
            return (this->id == id && this->mask == mask &&
                    this->handler == handler);
        }
    };

    vector<HandlerInfo> handlers_;

    // Index of the current iteration.
    size_t current_index_;
    // Points to a deleted entry in the vector, or -1.
    int pending_delete_index_;

    // These fields contain the message currently in progress.
    ID id_;

    // This notifiable tracks all the pending handlers.
    BarrierNotifiable children_;

    OSMutex lock_;

    TypedAllocator<DispatchFlow<ID>> allocator_;
};

template <typename ID, class Params>
class TypedDispatchFlow : public DispatchFlow<ID>
{
public:
    typedef ParamHandler<Params> Handler;

    TypedDispatchFlow(Executor* e) : DispatchFlow<ID>(e)
    {
    }

    TypedAllocator<TypedDispatchFlow<ID, Params>>* allocator()
    {
        return reinterpret_cast<TypedAllocator<TypedDispatchFlow<ID, Params>>*>(
            DispatchFlow<ID>::allocator());
    }

    /**
       Adds a new handler to this dispatcher.

       A handler will be called if incoming_id & mask == id & mask.

       @param id is the identifier of the message to listen to.
       @param mask is the mask of the ID matcher.
       @param handler is the handler. It must stay alive so long as this
       Dispatcher
       is alive.
     */
    void RegisterHandler(ID id, ID mask, Handler* handler)
    {
        DispatchFlow<ID>::RegisterHandler(id, mask, handler);
    }

    //! Removes a specific instance of a handler.
    void UnregisterHandler(ID id, ID mask, Handler* handler)
    {
        DispatchFlow<ID>::UnregisterHandler(id, mask, handler);
    }

    /** @returns the parameters structure to fill in before calling
        IncomingMessage. The caller must be in ownership of *this from an
        allocator before using this pointer.  */
    Params* mutable_params()
    {
        return &params_;
    }

protected:
    virtual void CallCurrentHandler(HandlerBase* b_handler, Notifiable* done)
    {
        Handler* handler = static_cast<Handler*>(b_handler);
        handler->handle_message(&params_, done);
    }

    Params params_;
};

// ================== IMPLEMENTATION ==================

template <typename ID>
DispatchFlow<ID>::DispatchFlow(Executor* executor)
    : ControlFlow(executor, nullptr), pending_delete_index_(-1)
{
    allocator_.Release(this);
}

template <typename ID> DispatchFlow<ID>::~DispatchFlow()
{
    HASSERT(IsNotStarted());
}

template <typename ID>
void DispatchFlow<ID>::RegisterHandler(ID id, ID mask, HandlerBase* handler)
{
    OSMutexLock h(&lock_);
    size_t idx = pending_delete_index_;
    while (idx < handlers_.size() && handlers_[idx].handler)
    {
        ++idx;
    }
    if (idx >= handlers_.size())
    {
        idx = handlers_.size();
        handlers_.resize(handlers_.size() + 1);
    }
    handlers_[idx].handler = handler;
    handlers_[idx].id = id;
    handlers_[idx].mask = mask;
}

template <typename ID>
void DispatchFlow<ID>::UnregisterHandler(ID id, ID mask, HandlerBase* handler)
{
    OSMutexLock h(&lock_);
    // First we try the current index - 1.
    size_t idx = current_index_;
    if (idx > 0)
        idx--;
    if (idx >= handlers_.size() || !handlers_[idx].Equals(id, mask, handler))
    {
        // We try all others too.
        idx = 0;
        while (idx < handlers_.size() &&
               !handlers_[idx].Equals(id, mask, handler))
            ++idx;
    }
    // Checks that we found the thing to unregister.
    HASSERT(idx < handlers_.size());
    handlers_[idx].handler = nullptr;
    if (pending_delete_index_ < 0 || idx < (size_t)pending_delete_index_)
    {
        pending_delete_index_ = idx;
    }
}

template <typename ID> void DispatchFlow<ID>::IncomingMessage(ID id)
{
    CheckNotStartedState();
    HASSERT(children_.IsDone());
    current_index_ = 0;
    id_ = id;
    children_.Reset(this);
    StartFlowAt(ST(HandleCall));
}

template <typename ID>
ControlFlow::ControlFlowAction DispatchFlow<ID>::HandleCall()
{
    HandlerBase* handler;
    {
        OSMutexLock l(&lock_);
        while (true)
        {
            if (current_index_ >= handlers_.size())
            {
                children_.MaybeDone();
                return WaitAndCall(ST(HandleWaitForChildren));
            }
            auto& h = handlers_[current_index_];
            ++current_index_;
            if (!h.handler)
            {
                continue;
            }
            if ((id_ & h.mask) != (h.id & h.mask))
            {
                continue;
            }
            handler = h.handler;
            break;
        }
    }
    AllocatorBase* a = handler->get_allocator();
    if (a)
    {
        return Allocate(a, ST(HandleAllocateResult));
    }
    else
    {
        CallCurrentHandler(handler, children_.NewChild());
        // Call went OK, proceed to the next handler to call.
        return RetryCurrentState();
    }
}

template <typename ID>
ControlFlow::ControlFlowAction DispatchFlow<ID>::HandleAllocateResult()
{
    HandlerBase* h;
    GetAllocationResult(&h);
    CallCurrentHandler(h, children_.NewChild());
    return CallImmediately(ST(HandleCall));
}

template <typename ID>
ControlFlow::ControlFlowAction DispatchFlow<ID>::HandleWaitForChildren()
{
    if (children_.IsDone())
    {
        if (OnFlowFinished())
        {
            // terminate flow.
            return ReleaseAndExit(&allocator_, this);
        }
        else
        {
            // The termination was taken care of by OnFlowFinished.
            return WaitForNotification();
        }
    }
    else
    {
        return WaitForNotification();
    }
}

#endif // _executor_Dispatcher_hxx_
<commit_msg>Adds a feature to the dispatcher to allow negative matching dispatchers to be created.<commit_after>/** \copyright
 * Copyright (c) 2013, Balazs Racz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file Dispatcher.hxx
 *
 * Class for dispatching incoming messages to handlers.
 *
 * @author Balazs Racz
 * @date 2 Dec 2013
 */

#ifndef _executor_Dispatcher_hxx_
#define _executor_Dispatcher_hxx_

#include <vector>

#include "executor/notifiable.hxx"
#include "executor/allocator.hxx"
#include "executor/control_flow.hxx"
#include "nmranet/NMRAnetIf.hxx"
#include "nmranet/NMRAnetNode.hxx"

/**
   Abstract class for handling an incoming message of a specifc MTI in NMRAnet.
   Handle calls are always made on the IF's read executor.

   There are two allocation mechanism available:

   . in one case the handler is directly able to process messages and performs
   the allocation itself. This is helpful for synchronous handlers, or when
   actual objects (instead of factories) are performing the handling of
   messages, such as when waiting for responses to outbound messages.

   . or the handler call actually returns an Allocator, which the caller has to
   acquire a handler from and re-post the same call to that handler.

   @TODO(balazs.racz): a handler base should probably not need to derive from
   queuemember.
 */
class HandlerBase : public QueueMember
{
public:
    /** Retrieves the allocator needed for a handler. The caller must retrieve
     * an instance from the allocator, or if the returned allocator is NULL,
     * then the caller may invoke this->handle_message immediately.
     *
     * @returns an allocator of type HandlerBase; or NULL.
     */
    virtual AllocatorBase* get_allocator()
    {
        return NULL;
    }
};

template <class Param> class ParamHandler : public HandlerBase
{
public:
    /**
     * Initiates handling of an incoming message.
     *
     * @param message is the incoming message. Does not take ownership.
     * @param done notifiable, will be notified when the message handling is
     * completed and message can be deallocated. Required.
     */
    virtual void handle_message(Param* message, Notifiable* done) = 0;
};

/**
   This class takes registered handlers for incoming messages. When a message
   shows up, all the handlers that match that message will be invoked. When all
   the handlers return, the message will be marked as completed, and the
   current flow will be released for further message calls.

   Handlers are called in no particular order.

   Allocation semantics:

   This flow is attached to a TypedAllocator owned by the If. The flow will
   return itself to the allocator automatically.
 */
template <typename ID> class DispatchFlow : public ControlFlow
{
public:
    DispatchFlow(Executor* executor);
    virtual ~DispatchFlow();
    /**
       Handles an incoming message. Prior to this call the parameters needed
       for the call should be injected into the flow using an
       implementation-specific method.

       @param id is the identifier of the incoming message.

       The flow *this will release itself to the allocator when the message
       handling is done.
     */
    void IncomingMessage(ID id);

    TypedAllocator<DispatchFlow<ID>>* allocator()
    {
        return &allocator_;
    }

    size_t handler_count()
    {
        size_t size = handlers_.size();
        if (pending_delete_index_ < 0)
            return size;
        for (int i = pending_delete_index_; i < (int)handlers_.size(); ++i)
        {
            if (handlers_[i].handler == nullptr)
                --size;
        }
        return size;
    }

protected:
    /**
       Adds a new handler to this dispatcher.

       A handler will be called if incoming_mti & mask == mti & mask.

       @param mti is the identifier of the message to listen to.
       @param mask is the mask of the mti matcher.
       @param handler is the MTI handler. It must stay alive so long as this If
       is alive.
     */
    void RegisterHandler(ID id, ID mask, HandlerBase* handler);

    //! Removes a specific instance of a handler from this IF.
    void UnregisterHandler(ID id, ID mask, HandlerBase* handler);

    /**
       Makes an implementation-specific call to the actual
       handler. Implementations will need to take certain handler arguments from
       member variables. The 'done' notifiable must be called in all cases.
     */
    virtual void CallCurrentHandler(HandlerBase* handler, Notifiable* done) = 0;

    /**
       This function will be called when the flow and all children are
       done. Useful for implementations to release memory and buffers
       associated with the current parameters.

       @returns true if the flow instance should be returned to the
       allocator. If returns false, must take care of changing the flow to a
       different state.
     */
    virtual bool OnFlowFinished()
    {
        return true;
    };

    virtual void CheckNotStartedState()
    {
        HASSERT(IsNotStarted());
    }

protected:
    // true if this flow should negate the match condition.
    bool negateMatch_;

private:
    // State handler. Calls the current handler.
    ControlFlowAction HandleCall();
    // State handler. If calling the handler didn't work, this state will be
    // called after the allocation.
    ControlFlowAction HandleAllocateResult();
    // State handler. Waits for the children to finish.
    ControlFlowAction HandleWaitForChildren();

    struct HandlerInfo
    {
        HandlerInfo() : handler(nullptr)
        {
        }
        ID id;
        ID mask;
        // NULL if the handler has been removed.
        HandlerBase* handler;

        bool Equals(ID id, ID mask, HandlerBase* handler)
        {
            return (this->id == id && this->mask == mask &&
                    this->handler == handler);
        }
    };

    vector<HandlerInfo> handlers_;

    // Index of the current iteration.
    size_t current_index_;
    // Points to a deleted entry in the vector, or -1.
    int pending_delete_index_;

    // These fields contain the message currently in progress.
    ID id_;

    // This notifiable tracks all the pending handlers.
    BarrierNotifiable children_;

    OSMutex lock_;

    TypedAllocator<DispatchFlow<ID>> allocator_;
};

template <typename ID, class Params>
class TypedDispatchFlow : public DispatchFlow<ID>
{
public:
    typedef ParamHandler<Params> Handler;

    TypedDispatchFlow(Executor* e) : DispatchFlow<ID>(e)
    {
    }

    TypedAllocator<TypedDispatchFlow<ID, Params>>* allocator()
    {
        return reinterpret_cast<TypedAllocator<TypedDispatchFlow<ID, Params>>*>(
            DispatchFlow<ID>::allocator());
    }

    /**
       Adds a new handler to this dispatcher.

       A handler will be called if incoming_id & mask == id & mask.

       @param id is the identifier of the message to listen to.
       @param mask is the mask of the ID matcher.
       @param handler is the handler. It must stay alive so long as this
       Dispatcher
       is alive.
     */
    void RegisterHandler(ID id, ID mask, Handler* handler)
    {
        DispatchFlow<ID>::RegisterHandler(id, mask, handler);
    }

    //! Removes a specific instance of a handler.
    void UnregisterHandler(ID id, ID mask, Handler* handler)
    {
        DispatchFlow<ID>::UnregisterHandler(id, mask, handler);
    }

    /** @returns the parameters structure to fill in before calling
        IncomingMessage. The caller must be in ownership of *this from an
        allocator before using this pointer.  */
    Params* mutable_params()
    {
        return &params_;
    }

protected:
    virtual void CallCurrentHandler(HandlerBase* b_handler, Notifiable* done)
    {
        Handler* handler = static_cast<Handler*>(b_handler);
        handler->handle_message(&params_, done);
    }

    Params params_;
};

// ================== IMPLEMENTATION ==================

template <typename ID>
DispatchFlow<ID>::DispatchFlow(Executor* executor)
    : ControlFlow(executor, nullptr),
      negateMatch_(false),
      pending_delete_index_(-1)
{
    allocator_.Release(this);
}

template <typename ID> DispatchFlow<ID>::~DispatchFlow()
{
    HASSERT(IsNotStarted());
}

template <typename ID>
void DispatchFlow<ID>::RegisterHandler(ID id, ID mask, HandlerBase* handler)
{
    OSMutexLock h(&lock_);
    size_t idx = pending_delete_index_;
    while (idx < handlers_.size() && handlers_[idx].handler)
    {
        ++idx;
    }
    if (idx >= handlers_.size())
    {
        idx = handlers_.size();
        handlers_.resize(handlers_.size() + 1);
    }
    handlers_[idx].handler = handler;
    handlers_[idx].id = id;
    handlers_[idx].mask = mask;
}

template <typename ID>
void DispatchFlow<ID>::UnregisterHandler(ID id, ID mask, HandlerBase* handler)
{
    OSMutexLock h(&lock_);
    // First we try the current index - 1.
    size_t idx = current_index_;
    if (idx > 0)
        idx--;
    if (idx >= handlers_.size() || !handlers_[idx].Equals(id, mask, handler))
    {
        // We try all others too.
        idx = 0;
        while (idx < handlers_.size() &&
               !handlers_[idx].Equals(id, mask, handler))
            ++idx;
    }
    // Checks that we found the thing to unregister.
    HASSERT(idx < handlers_.size());
    handlers_[idx].handler = nullptr;
    if (pending_delete_index_ < 0 || idx < (size_t)pending_delete_index_)
    {
        pending_delete_index_ = idx;
    }
}

template <typename ID> void DispatchFlow<ID>::IncomingMessage(ID id)
{
    CheckNotStartedState();
    HASSERT(children_.IsDone());
    current_index_ = 0;
    id_ = id;
    children_.Reset(this);
    StartFlowAt(ST(HandleCall));
}

template <typename ID>
ControlFlow::ControlFlowAction DispatchFlow<ID>::HandleCall()
{
    HandlerBase* handler;
    {
        OSMutexLock l(&lock_);
        while (true)
        {
            if (current_index_ >= handlers_.size())
            {
                children_.MaybeDone();
                return WaitAndCall(ST(HandleWaitForChildren));
            }
            auto& h = handlers_[current_index_];
            ++current_index_;
            if (!h.handler)
            {
                continue;
            }
            if (negateMatch_ && (id_ & h.mask) == (h.id & h.mask))
            {
                continue;
            }
            if ((!negateMatch_) && (id_ & h.mask) != (h.id & h.mask))
            {
                continue;
            }
            handler = h.handler;
            break;
        }
    }
    AllocatorBase* a = handler->get_allocator();
    if (a)
    {
        return Allocate(a, ST(HandleAllocateResult));
    }
    else
    {
        CallCurrentHandler(handler, children_.NewChild());
        // Call went OK, proceed to the next handler to call.
        return RetryCurrentState();
    }
}

template <typename ID>
ControlFlow::ControlFlowAction DispatchFlow<ID>::HandleAllocateResult()
{
    HandlerBase* h;
    GetAllocationResult(&h);
    CallCurrentHandler(h, children_.NewChild());
    return CallImmediately(ST(HandleCall));
}

template <typename ID>
ControlFlow::ControlFlowAction DispatchFlow<ID>::HandleWaitForChildren()
{
    if (children_.IsDone())
    {
        if (OnFlowFinished())
        {
            // terminate flow.
            return ReleaseAndExit(&allocator_, this);
        }
        else
        {
            // The termination was taken care of by OnFlowFinished.
            return WaitForNotification();
        }
    }
    else
    {
        return WaitForNotification();
    }
}

#endif // _executor_Dispatcher_hxx_
<|endoftext|>


<commit_before>/*
*
* Copyright 2013 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker 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 Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* fermin at tid dot es
*
* Author: Ken Zangelin
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <string>

#include "logMsg/logMsg.h"

#include "common/globals.h"
#include "common/string.h"
#include "common/tag.h"
#include "ngsi/Request.h"
#include "common/Format.h"
#include "rest/HttpStatusCode.h"
#include "ngsi/StatusCode.h"

/* ****************************************************************************
*
* StatusCode::StatusCode -
*/
StatusCode::StatusCode()
{
  code         = SccNone;
  reasonPhrase = "";
  details      = "";
  tag          = "statusCode";
}

/* ****************************************************************************
*
* StatusCode::StatusCode -
*/
StatusCode::StatusCode(const std::string& _tag)
{
  code         = SccNone;
  reasonPhrase = "";
  details      = "";
  tag          = _tag;
}

/* ****************************************************************************
*
* StatusCode::StatusCode -
*/
StatusCode::StatusCode(HttpStatusCode _code, const std::string& _details, const std::string& _tag)
{
  code          = _code;
  reasonPhrase  = httpStatusCodeString(code);
  details       = _details;
  tag           = _tag;
}

extern char* curl_escape(const char*, int);
/* ****************************************************************************
*
* StatusCode::render -
*/
std::string StatusCode::render(Format format, const std::string& indent, bool comma, bool showTag)
{
  std::string  out  = "";

  if (strstr(details.c_str(), "\"") != NULL)
  {
    char* s2    = (char*) calloc(1, details.length() * 2 + 1);

    strReplace(s2, details.c_str(), "\"", "\\\"");
    details = s2;
    free(s2);
  }

  if (code == SccNone)
  {
    fill(SccReceiverInternalError, "");
    details += " - ZERO code set to 500";
  }

  out += startTag(indent, tag, format, showTag);
  out += valueTag(indent + "  ", "code", code, format, true);
  out += valueTag(indent + "  ", "reasonPhrase", reasonPhrase, format, details != "");

  if (details != "")
     out += valueTag(indent + "  ", "details", details, format, false);

  out += endTag(indent, tag, format, comma);

  return out;
}

/* ****************************************************************************
*
* StatusCode::fill -
*/
void StatusCode::fill(HttpStatusCode _code, const std::string& _details)
{
   code          = _code;
   reasonPhrase  = httpStatusCodeString(code);
   details       = _details;
}

/* ****************************************************************************
*
* StatusCode::fill -
*/
void StatusCode::fill(StatusCode* scP)
{
   fill(scP->code, scP->details);
}

/* ****************************************************************************
*
* StatusCode::check -
*/
std::string StatusCode::check(RequestType requestType, Format format, const std::string& indent, const std::string& predetectedError, int counter)
{
  if (code == SccNone)
    return "no code";

  if (reasonPhrase == "")
    return "no reason phrase";

  return "OK";
}

/* ****************************************************************************
*
* StatusCode::present -
*/
void StatusCode::present(const std::string& indent)
{
   PRINTF("%sCode:            %d\n",   indent.c_str(), code);
   PRINTF("%sReasonPhrase:    '%s'\n", indent.c_str(), reasonPhrase.c_str());
   PRINTF("%sDetail:          '%s'\n", indent.c_str(), details.c_str());
   PRINTF("%sTag:             '%s'\n", indent.c_str(), tag.c_str());
}

/* ****************************************************************************
*
* release -
*/
void StatusCode::release(void)
{
  code         = SccNone;
  reasonPhrase = "";
  details      = "";
}

/* ****************************************************************************
*
* tagSet -
*/
void StatusCode::tagSet(const std::string& _tag)
{
  tag = _tag;
}
<commit_msg>removed rests of curl-test that had remained in this file<commit_after>/*
*
* Copyright 2013 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker 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 Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* fermin at tid dot es
*
* Author: Ken Zangelin
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string>

#include "logMsg/logMsg.h"

#include "common/globals.h"
#include "common/string.h"
#include "common/tag.h"
#include "ngsi/Request.h"
#include "common/Format.h"
#include "rest/HttpStatusCode.h"
#include "ngsi/StatusCode.h"

/* ****************************************************************************
*
* StatusCode::StatusCode -
*/
StatusCode::StatusCode()
{
  code         = SccNone;
  reasonPhrase = "";
  details      = "";
  tag          = "statusCode";
}

/* ****************************************************************************
*
* StatusCode::StatusCode -
*/
StatusCode::StatusCode(const std::string& _tag)
{
  code         = SccNone;
  reasonPhrase = "";
  details      = "";
  tag          = _tag;
}

/* ****************************************************************************
*
* StatusCode::StatusCode -
*/
StatusCode::StatusCode(HttpStatusCode _code, const std::string& _details, const std::string& _tag)
{
  code          = _code;
  reasonPhrase  = httpStatusCodeString(code);
  details       = _details;
  tag           = _tag;
}

/* ****************************************************************************
*
* StatusCode::render -
*/
std::string StatusCode::render(Format format, const std::string& indent, bool comma, bool showTag)
{
  std::string  out  = "";

  if (strstr(details.c_str(), "\"") != NULL)
  {
    char* s2    = (char*) calloc(1, details.length() * 2 + 1);

    strReplace(s2, details.c_str(), "\"", "\\\"");
    details = s2;
    free(s2);
  }

  if (code == SccNone)
  {
    fill(SccReceiverInternalError, "");
    details += " - ZERO code set to 500";
  }

  out += startTag(indent, tag, format, showTag);
  out += valueTag(indent + "  ", "code", code, format, true);
  out += valueTag(indent + "  ", "reasonPhrase", reasonPhrase, format, details != "");

  if (details != "")
     out += valueTag(indent + "  ", "details", details, format, false);

  out += endTag(indent, tag, format, comma);

  return out;
}

/* ****************************************************************************
*
* StatusCode::fill -
*/
void StatusCode::fill(HttpStatusCode _code, const std::string& _details)
{
   code          = _code;
   reasonPhrase  = httpStatusCodeString(code);
   details       = _details;
}

/* ****************************************************************************
*
* StatusCode::fill -
*/
void StatusCode::fill(StatusCode* scP)
{
   fill(scP->code, scP->details);
}

/* ****************************************************************************
*
* StatusCode::check -
*/
std::string StatusCode::check(RequestType requestType, Format format, const std::string& indent, const std::string& predetectedError, int counter)
{
  if (code == SccNone)
    return "no code";

  if (reasonPhrase == "")
    return "no reason phrase";

  return "OK";
}

/* ****************************************************************************
*
* StatusCode::present -
*/
void StatusCode::present(const std::string& indent)
{
   PRINTF("%sCode:            %d\n",   indent.c_str(), code);
   PRINTF("%sReasonPhrase:    '%s'\n", indent.c_str(), reasonPhrase.c_str());
   PRINTF("%sDetail:          '%s'\n", indent.c_str(), details.c_str());
   PRINTF("%sTag:             '%s'\n", indent.c_str(), tag.c_str());
}

/* ****************************************************************************
*
* release -
*/
void StatusCode::release(void)
{
  code         = SccNone;
  reasonPhrase = "";
  details      = "";
}

/* ****************************************************************************
*
* tagSet -
*/
void StatusCode::tagSet(const std::string& _tag)
{
  tag = _tag;
}
<|endoftext|>


<commit_before>#include "cmainwindow.h"
#include "ui_cmainwindow.h"

#include <QCameraInfo>
#include <QImageReader>
#include <QPainter>
#include <QTime>
#include <QTimer>

inline bool analyzeFrame(const QImage& frame, unsigned int threshold)
{
	if (frame.depth() != 32)
		return true;

	const int w = frame.width(), h = frame.height();
	const int sampleSquareSize = 20;
	const int sampleStrideW = w / sampleSquareSize, sampleStrideH = h / sampleSquareSize;
	uint64_t pixelsValueSum = 0;
	for (int y = 0; y < h; y += sampleStrideH)
	{
		const uint32_t* scanLine = (const uint32_t*) frame.scanLine(y);
		for (int x = 0; x < w; x += sampleStrideW)
		{
			// TODO: support non-32 bpp images
			// TODO: vectorization
			const uint32_t pixel = scanLine[y];
			pixelsValueSum += ((pixel & 0x00FF0000) >> 16) + ((pixel & 0x0000FF00) >> 8) + (pixel & 0x000000FF);
		}
	}

	const auto avgValue = pixelsValueSum / ((uint64_t) w / sampleStrideW * (uint64_t) h / sampleStrideH * 3ull);
	qDebug() << "Frame metric:" << avgValue;
	return avgValue >= threshold;
}

CMainWindow::CMainWindow(QWidget *parent) :
	QMainWindow(parent),
	ui(new Ui::CMainWindow)
{
	ui->setupUi(this);

	ui->_displayWidget->installEventFilter(this);

	connect(&_frameGrabber, &ProxyVideoSurface::frameReceived, [this](QImage frame) {
		if (!frame.isNull() && ui->_btnEnableProbing->isChecked())
		{
			// This is the first frame upon connecting to the camera
			if (_frame.isNull())
			{
				if (!analyzeFrame(frame, ui->_threshold->value()))
				{
					// Disconnect and schedule re-check
					disconnectFromCamera();
					QTimer::singleShot(7000, [this](){
						connectToCamera();
					});
				}
			}
			else // Not the first frame - apparently, we're streaming a live picture
				 // Avoid checking every single frame
			{
				static uint32_t frameCounter = 0;
				++frameCounter;

				if (frameCounter > 50)
				{
					frameCounter = 0;
					if (!analyzeFrame(frame, ui->_threshold->value()))
					{
						// Diisconnect and schedule re-check
						disconnectFromCamera();
						QTimer::singleShot(7000, [this](){
							connectToCamera();
						});
					}
				}
			}
		}

		_frame = frame;
		ui->_displayWidget->update();
	});

	connect(ui->_btnConnect, &QPushButton::toggled, [this](bool connect){
		ui->_btnConnect->setChecked(!connect);
		if (connect)
			connectToCamera();
		else
			disconnectFromCamera();
	});

	connectToCamera();
}

CMainWindow::~CMainWindow()
{
	disconnectFromCamera();
	delete ui;
}

bool CMainWindow::eventFilter(QObject* /*object*/, QEvent* event)
{
	if (event->type() == QEvent::Paint)
	{
		QWidget * widget = ui->_displayWidget;
		QPainter painter(widget);
		if (!_frame.isNull())
			painter.drawImage(widget->geometry(), _frame);
		else
			painter.fillRect(widget->geometry(), Qt::darkGray);
		painter.end();
	}

	return false;
}

void CMainWindow::connectToCamera()
{
	const auto cameras = QCameraInfo::availableCameras();
	if (cameras.empty())
		return;

	const auto& cameraInfo = cameras.front();
	if (cameraInfo.isNull())
		return;

	qDebug() << "Creating the camera" << cameraInfo.description();
	_camera = std::make_shared<QCamera>(cameraInfo);
	_camera->setViewfinder(&_frameGrabber);

	qDebug() << "Connecting to the camera";
	connect(_camera.get(), &QCamera::stateChanged, [this](const QCamera::State state){
		if (state == QCamera::ActiveState)
		{
			ui->_btnConnect->setChecked(true);
			setWindowTitle("Connected");
		}
		else
		{
			ui->_btnConnect->setChecked(false);
			setWindowTitle("Not Connected");
		}
	});

	_camera->start();
}

void CMainWindow::disconnectFromCamera()
{
	if (_camera)
	{
		_camera->stop();
		_camera->setViewfinder((QAbstractVideoSurface*)nullptr);
		_frame = QImage();
	}

	_camera.reset();
	setWindowTitle("Not Connected");
}
<commit_msg>Stack overflow fixed<commit_after>#include "cmainwindow.h"
#include "ui_cmainwindow.h"

#include <QCameraInfo>
#include <QImageReader>
#include <QPainter>
#include <QTime>
#include <QTimer>

inline bool analyzeFrame(const QImage& frame, unsigned int threshold)
{
	if (frame.depth() != 32)
		return true;

	const int w = frame.width(), h = frame.height();
	const int sampleSquareSize = 20;
	const int sampleStrideW = w / sampleSquareSize, sampleStrideH = h / sampleSquareSize;
	uint64_t pixelsValueSum = 0;
	for (int y = 0; y < h; y += sampleStrideH)
	{
		const uint32_t* scanLine = (const uint32_t*) frame.scanLine(y);
		for (int x = 0; x < w; x += sampleStrideW)
		{
			// TODO: support non-32 bpp images
			// TODO: vectorization
			const uint32_t pixel = scanLine[y];
			pixelsValueSum += ((pixel & 0x00FF0000) >> 16) + ((pixel & 0x0000FF00) >> 8) + (pixel & 0x000000FF);
		}
	}

	const auto avgValue = pixelsValueSum / ((uint64_t) w / sampleStrideW * (uint64_t) h / sampleStrideH * 3ull);
	qDebug() << "Frame metric:" << avgValue;
	return avgValue >= threshold;
}

CMainWindow::CMainWindow(QWidget *parent) :
	QMainWindow(parent),
	ui(new Ui::CMainWindow)
{
	ui->setupUi(this);

	ui->_displayWidget->installEventFilter(this);

	connect(&_frameGrabber, &ProxyVideoSurface::frameReceived, [this](QImage frame) {
		if (!frame.isNull() && ui->_btnEnableProbing->isChecked())
		{
			// This is the first frame upon connecting to the camera
			if (_frame.isNull())
			{
				if (!analyzeFrame(frame, ui->_threshold->value()))
				{
					// Disconnect and schedule re-check
					disconnectFromCamera();
					QTimer::singleShot(7000, [this](){
						connectToCamera();
					});
				}
			}
			else // Not the first frame - apparently, we're streaming a live picture
				 // Avoid checking every single frame
			{
				static uint32_t frameCounter = 0;
				++frameCounter;

				if (frameCounter > 50)
				{
					frameCounter = 0;
					if (!analyzeFrame(frame, ui->_threshold->value()))
					{
						// Diisconnect and schedule re-check
						disconnectFromCamera();
						QTimer::singleShot(7000, [this](){
							connectToCamera();
						});
					}
				}
			}
		}

		_frame = frame;
		ui->_displayWidget->update();
	});

	connect(ui->_btnConnect, &QPushButton::clicked, [this](bool connect){
		ui->_btnConnect->setChecked(!connect);
		if (connect)
			connectToCamera();
		else
			disconnectFromCamera();
	});

	connectToCamera();
}

CMainWindow::~CMainWindow()
{
	disconnectFromCamera();
	delete ui;
}

bool CMainWindow::eventFilter(QObject* /*object*/, QEvent* event)
{
	if (event->type() == QEvent::Paint)
	{
		QWidget * widget = ui->_displayWidget;
		QPainter painter(widget);
		if (!_frame.isNull())
			painter.drawImage(widget->geometry(), _frame);
		else
			painter.fillRect(widget->geometry(), Qt::darkGray);
		painter.end();
	}

	return false;
}

void CMainWindow::connectToCamera()
{
	const auto cameras = QCameraInfo::availableCameras();
	if (cameras.empty())
		return;

	const auto& cameraInfo = cameras.front();
	if (cameraInfo.isNull())
		return;

	qDebug() << "Creating the camera" << cameraInfo.description();
	_camera = std::make_shared<QCamera>(cameraInfo);
	_camera->setViewfinder(&_frameGrabber);

	qDebug() << "Connecting to the camera";
	connect(_camera.get(), &QCamera::stateChanged, [this](const QCamera::State state){
		if (state == QCamera::ActiveState)
		{
			ui->_btnConnect->setChecked(true);
			setWindowTitle("Connected");
		}
		else
		{
			ui->_btnConnect->setChecked(false);
			setWindowTitle("Not Connected");
		}
	});

	_camera->start();
}

void CMainWindow::disconnectFromCamera()
{
	if (_camera)
	{
		_camera->stop();
		_camera->setViewfinder((QAbstractVideoSurface*)nullptr);
		_frame = QImage();
	}

	_camera.reset();
	setWindowTitle("Not Connected");
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 Andrew Toulouse.
// Distributed under the MIT License.

#include "PlayerSegment.h"

#include <cstring>
#include <fstream>
#include <iostream>

namespace libol {
    bool PlayerSegment::probe(std::ifstream& ifs) {
        auto pos = ifs.tellg();
        ifs.ignore(2);
        uint8_t test = ifs.get();
        ifs.seekg(pos);

        return test == 0xC3;
    }

    PlayerSegment PlayerSegment::decode(std::ifstream& ifs) {
        PlayerSegment player;

        // Header
        ifs.read(reinterpret_cast<char *>(player.header.data()), player.header.size());

        // Summoner name
        char summonerChars[0x81];
        ifs.read(summonerChars, 0x80);
        summonerChars[0x80] = 0x00;
        player.summonerName = summonerChars;

        // Champion name
        char championChars[0x11];
        ifs.read(championChars, 0x10);
        summonerChars[0x10] = 0x00;
        player.championName = championChars;

        // Unknown 0
        ifs.read(reinterpret_cast<char *>(player.unk0.data()), player.unk0.size());

        // Runes
        ifs.read(reinterpret_cast<char *>(player.runes.data()), player.runes.size() * 4);

        // Masteries
        ifs.read(reinterpret_cast<char *>(player.masteriesHeader.data()), player.masteriesHeader.size());
        auto pos = ifs.tellg();
        int masteryCount = 0;
        while(MasteryEntry::probe(ifs) && masteryCount < 79) {
            player.masteries.push_back(MasteryEntry::decode(ifs));
            masteryCount++;
        }
        ifs.seekg(pos);
        ifs.ignore(0x18C); // Jump over entire section
        while(!ifs.peek()) ifs.ignore(1); // Padding

        // Items
        ifs.read(reinterpret_cast<char *>(player.itemsHeader.data()), player.itemsHeader.size());
        for(int i = 0; i < player.items.size(); i++) {
            player.items[i] = ItemEntry::decode(ifs);
        }

        for(int i = 0; i < player.items.size(); i++) {
            player.items[i].decodeCooldown(ifs);
        }

        for(int i = 0; i < player.items.size(); i++) {
            player.items[i].decodeBaseCooldown(ifs);
        }

        // Playerdata
        ifs.ignore(0x0C /* or 0x0F ? */); // Ignore playerData header
        ifs.read(reinterpret_cast<char *>(&player.playerData), sizeof(player.playerData));
        // Sometimes 0xE data follows:
        while(ifs.peek() < 0x70) // TODO: Detect this better
            ifs.ignore(1);

        // Abilities
        ifs.ignore(0x04); // Ignore abilities header
        for(int i = 0; i < player.abilities.size(); i++) {
            player.abilities[i] = AbilityEntry::decode(ifs);
        }

        // Footer
        uint8_t marker[] = {0x00, 0x00, 0x15, 0x01}; // Search for this
        char buf[sizeof(marker)];
        while(true) {
            auto pos = ifs.tellg();
            ifs.read(buf, sizeof(marker));
            if(ifs.eof()) {
                std::cout << "footer not found" << std::endl;
                exit(1);
            }
            ifs.seekg(pos);
            if(!memcmp((void*) marker, (void*) buf, sizeof(marker)))
                break;
            ifs.ignore(1);
        }
        ifs.read(reinterpret_cast<char *>(player.footer.data()), player.footer.size());

        return player;
    }
}
<commit_msg>Item replacement<commit_after>// Copyright (c) 2014 Andrew Toulouse.
// Distributed under the MIT License.

#include "PlayerSegment.h"

#include <cstring>
#include <fstream>
#include <iostream>

namespace libol {
    bool PlayerSegment::probe(std::ifstream& ifs) {
        auto pos = ifs.tellg();
        ifs.ignore(2);
        uint8_t test = ifs.get();
        ifs.seekg(pos);

        return test == 0xC3;
    }

    PlayerSegment PlayerSegment::decode(std::ifstream& ifs) {
        PlayerSegment player;

        // Header
        ifs.read(reinterpret_cast<char *>(player.header.data()), player.header.size());

        // Summoner name
        char summonerChars[0x81];
        ifs.read(summonerChars, 0x80);
        summonerChars[0x80] = 0x00;
        player.summonerName = summonerChars;

        // Champion name
        char championChars[0x11];
        ifs.read(championChars, 0x10);
        summonerChars[0x10] = 0x00;
        player.championName = championChars;

        // Unknown 0
        ifs.read(reinterpret_cast<char *>(player.unk0.data()), player.unk0.size());

        // Runes
        ifs.read(reinterpret_cast<char *>(player.runes.data()), player.runes.size() * 4);

        // Masteries
        ifs.read(reinterpret_cast<char *>(player.masteriesHeader.data()), player.masteriesHeader.size());
        auto pos = ifs.tellg();
        int masteryCount = 0;
        while(MasteryEntry::probe(ifs) && masteryCount < 79) {
            player.masteries.push_back(MasteryEntry::decode(ifs));
            masteryCount++;
        }
        ifs.seekg(pos);
        ifs.ignore(0x18C); // Jump over entire section
        while(!ifs.peek()) ifs.ignore(1); // Padding

        // Items
        ifs.read(reinterpret_cast<char *>(player.itemsHeader.data()), player.itemsHeader.size());
        for(int i = 0; i < player.items.size(); i++) {
            player.items[i] = ItemEntry::decode(ifs);
        }
        for(int i = 0; i < player.items.size(); i++) {
            player.items[i].decodeCooldown(ifs);
        }
        for(int i = 0; i < player.items.size(); i++) {
            player.items[i].decodeBaseCooldown(ifs);
        }
        if(ifs.peek() == 0xF3) // Item replacements
            ifs.ignore(0xE);

        // Playerdata
        ifs.ignore(0x0C /* or 0x0F ? */); // Ignore playerData header
        ifs.read(reinterpret_cast<char *>(&player.playerData), sizeof(player.playerData));

        // Abilities
        ifs.ignore(0x04); // Ignore abilities header
        for(int i = 0; i < player.abilities.size(); i++) {
            player.abilities[i] = AbilityEntry::decode(ifs);
        }

        // Footer
        uint8_t marker[] = {0x00, 0x00, 0x15, 0x01}; // Search for this
        char buf[sizeof(marker)];
        while(true) {
            auto pos = ifs.tellg();
            ifs.read(buf, sizeof(marker));
            if(ifs.eof()) {
                std::cout << "footer not found" << std::endl;
                exit(1);
            }
            ifs.seekg(pos);
            if(!memcmp((void*) marker, (void*) buf, sizeof(marker)))
                break;
            ifs.ignore(1);
        }
        ifs.read(reinterpret_cast<char *>(player.footer.data()), player.footer.size());

        return player;
    }
}
<|endoftext|>


<commit_before>#include <QCoreApplication>
#include "testbase.h"
#include "testcreatefile.h"
#include "testcreatedirectory.h"
#include "testdeletedirectory.h"
#include "testdeletefiles.h"

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

    TestRunner testRunner;
    testRunner
              << new CreateFilesTestCase()
              << new CreateDirectoriesTestCase()
               << new DeleteDirectoriesTestCase()
                 ;
    testRunner.run();
    return a.exec();
}
<commit_msg>one test was missing.<commit_after>#include <QCoreApplication>
#include "testbase.h"
#include "testcreatefile.h"
#include "testcreatedirectory.h"
#include "testdeletedirectory.h"
#include "testdeletefiles.h"

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

    TestRunner testRunner;
    testRunner
              << new CreateFilesTestCase()
              << new CreateDirectoriesTestCase()
              << new DeleteDirectoriesTestCase()
              << new CreateDirectoriesTestCase()
                 ;
    testRunner.run();
    return a.exec();
}
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright 2011-2013 The University of North Carolina at Chapel Hill
 *  All rights reserved.
 *
 *  Licensed under the MADAI Software License. You may obtain a copy of
 *  this license at
 *
 *         https://madai-public.cs.unc.edu/visualization/software-license/
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include <cassert>
#include <cstdlib>
#include <iomanip>

#include "SamplerCSVWriter.h"
#include "Sample.h"
#include "Sampler.h"
#include "Model.h"

namespace madai {

int SamplerCSVWriter
::GenerateSamplesAndSaveToFile(
    Sampler & sampler,
    Model & model,
    std::ostream & outFile,
    int NumberOfSamples,
    int NumberOfBurnInSamples,
    bool UseEmulatorCovariance,
    bool WriteLogLikelihoodGradients,
    std::ostream * progress)
{
  model.SetUseModelCovarianceToCalulateLogLikelihood(UseEmulatorCovariance);
  sampler.SetModel( &model );

  enum phase { burnIn = 0, traceGeneration = 1 };
  int currentNumberOfSamples[2] = { NumberOfBurnInSamples, NumberOfSamples };
  const char * currentName[2] = {"Burn in", "Sampler"};
  double bestLogLikelihood = 0;
  Sample oldSample = sampler.NextSample();
  for ( int currentPhase = burnIn; currentPhase <= traceGeneration; currentPhase++ ) {
    int step = currentNumberOfSamples[currentPhase] / 100, percent = 1;
    if ( step < 1 ) {
      step = 1; // avoid div-by-zero error
    }
    int successfulSteps = 0, failedSteps = 0;
    for ( int count = 0; count < currentNumberOfSamples[currentPhase]; count++ ) {
      Sample sample = sampler.NextSample();
      if ( sample == oldSample ) {
        failedSteps++;
      }
      else {
        successfulSteps++;
      }
      oldSample = sample;

      WriteSample( outFile, sample );

      if ( sample.m_LogLikelihood > bestLogLikelihood || ( currentPhase == burnIn && count == 0 ) ) {
        bestLogLikelihood = sample.m_LogLikelihood;
      }

      if ( progress != NULL ) {
        if ( ( count + 1 ) % step == 0 ) {
          (*progress) <<  '\r' << currentName[currentPhase] << " percent done: " << std::setfill('0') << std::setw(2) << percent++ << "%";
          (*progress) << "  Success rate: " << std::setfill('0') << std::setw(2) << 100*successfulSteps / (successfulSteps + failedSteps) << "%";
          (*progress) << "  Best log likelihood: " << bestLogLikelihood;
        }
        progress->flush();
      }
    }
    if ( currentPhase == burnIn ) {
      WriteHeader( outFile, model.GetParameters(), model.GetScalarOutputNames() );
    }
    if ( progress != NULL ) {
      // Leave the success rate percentage visible
      (*progress) << "\n";
      progress->flush();
    }
  }

  return EXIT_SUCCESS;
}

void
SamplerCSVWriter
::WriteHeader( std::ostream & o,
               const std::vector< Parameter > & params,
               const std::vector< std::string > & outputs,
               bool WriteLogLikelihoodGradients)
{
  if ( !params.empty() ) {
    std::vector< Parameter >::const_iterator itr = params.begin();
    o << '"' << itr->m_Name << '"';
    for ( itr++; itr < params.end(); itr++ ) {
      o << ',' << '"' << itr->m_Name << '"';
    }
    if ( !outputs.empty() ) {
      o << ',';
    }
  }
  if ( !outputs.empty() ) {
    std::vector<std::string>::const_iterator itr = outputs.begin();
    //std::cout << "Output name: " << *itr << std::endl;
    o << '"' << *itr << '"';
    for ( itr++; itr < outputs.end(); itr++ ) {
      o << ',' << '"' << *itr << '"';
    }
  }
  o << ",\"LogLikelihood\"";
  if( WriteLogLikelihoodGradients ) {
    if ( !outputs.empty() ) {
      for ( std::vector<std::string>::const_iterator itr = outputs.begin();
            itr < outputs.end(); itr++ )
      {
        o << ',' << "\"dLL/d" << *itr << '"';
      }
      for ( std::vector<std::string>::const_iterator itr = outputs.begin();
            itr < outputs.end(); itr++ )
      {
        o << ',' << "\"sigma_" << *itr << "*dLL/dsigma_" << *itr << '"';
      }
    }
  }
  o << "\n";
}

/** Utility for writing a vector to an output stream
 *
 * The vector elements are delimited by the given delimiter */
template <class T>
void write_vector( std::ostream& o, std::vector< T > const & v, char delim ) {
  if ( !v.empty() ) {
    typename std::vector< T >::const_iterator itr = v.begin();
    o << *(itr++);
    while ( itr < v.end() ) {
      o << delim << *(itr++);
    }
  }
}

void
SamplerCSVWriter
::WriteSample( std::ostream & out, const Sample & sample,
            bool WriteLogLikelihoodGradients)
{
  write_vector( out, sample.m_ParameterValues, ',' );
  out << ',';

  if ( sample.m_OutputValues.size() > 0 ) {
    write_vector( out, sample.m_OutputValues, ',' );
    out << ',';
  }
  out << sample.m_LogLikelihood;
  if( WriteLogLikelihoodGradients ) {
    if ( sample.m_OutputValues.size() > 0 ) {
      out << ',';
      write_vector( out, sample.m_LogLikelihoodValueGradient, ',' );
      out << ',';
      write_vector( out, sample.m_LogLikelihoodErrorGradient, ',' );
    }
  }
  if ( sample.m_Comments.size() > 0 ) {
    out << ",\"";
    write_vector( out, sample.m_Comments, ';' );
    out << '"';
  }
  out << '\n';

  out.flush();
}

} // end namespace madai
<commit_msg>Pulled in fix to CSV writer from master.<commit_after>/*=========================================================================
 *
 *  Copyright 2011-2013 The University of North Carolina at Chapel Hill
 *  All rights reserved.
 *
 *  Licensed under the MADAI Software License. You may obtain a copy of
 *  this license at
 *
 *         https://madai-public.cs.unc.edu/visualization/software-license/
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include <cassert>
#include <cstdlib>
#include <iomanip>

#include "SamplerCSVWriter.h"
#include "Sample.h"
#include "Sampler.h"
#include "Model.h"

namespace madai {

int SamplerCSVWriter
::GenerateSamplesAndSaveToFile(
    Sampler & sampler,
    Model & model,
    std::ostream & outFile,
    int NumberOfSamples,
    int NumberOfBurnInSamples,
    bool UseEmulatorCovariance,
    bool WriteLogLikelihoodGradients,
    std::ostream * progress)
{
  model.SetUseModelCovarianceToCalulateLogLikelihood(UseEmulatorCovariance);
  sampler.SetModel( &model );

  enum phase { burnIn = 0, traceGeneration = 1 };
  int currentNumberOfSamples[2] = { NumberOfBurnInSamples, NumberOfSamples };
  const char * currentName[2] = {"Burn in", "Sampler"};
  double bestLogLikelihood = 0;
  Sample oldSample = sampler.NextSample();
  for ( int currentPhase = burnIn; currentPhase <= traceGeneration; currentPhase++ ) {
    int step = currentNumberOfSamples[currentPhase] / 100, percent = 1;
    if ( step < 1 ) {
      step = 1; // avoid div-by-zero error
    }
    int successfulSteps = 0, failedSteps = 0;
    for ( int count = 0; count < currentNumberOfSamples[currentPhase]; count++ ) {
      Sample sample = sampler.NextSample();
      if ( sample == oldSample ) {
        failedSteps++;
      }
      else {
        successfulSteps++;
      }
      oldSample = sample;

      if ( currentPhase == traceGeneration ) {
        WriteSample( outFile, sample, WriteLogLikelihoodGradients );
      }

      if ( sample.m_LogLikelihood > bestLogLikelihood || ( currentPhase == burnIn && count == 0 ) ) {
        bestLogLikelihood = sample.m_LogLikelihood;
      }

      if ( progress != NULL ) {
        if ( ( count + 1 ) % step == 0 ) {
          (*progress) <<  '\r' << currentName[currentPhase] << " percent done: " << std::setfill('0') << std::setw(2) << percent++ << "%";
          (*progress) << "  Success rate: " << std::setfill('0') << std::setw(2) << 100*successfulSteps / (successfulSteps + failedSteps) << "%";
          (*progress) << "  Best log likelihood: " << bestLogLikelihood;
        }
        progress->flush();
      }
    }
    if ( currentPhase == burnIn ) {
      WriteHeader( outFile, model.GetParameters(), model.GetScalarOutputNames(), WriteLogLikelihoodGradients );
    }
    if ( progress != NULL ) {
      // Leave the success rate percentage visible
      (*progress) << "\n";
      progress->flush();
    }
  }

  return EXIT_SUCCESS;
}

void
SamplerCSVWriter
::WriteHeader( std::ostream & o,
               const std::vector< Parameter > & params,
               const std::vector< std::string > & outputs,
               bool WriteLogLikelihoodGradients)
{
  if ( !params.empty() ) {
    std::vector< Parameter >::const_iterator itr = params.begin();
    o << '"' << itr->m_Name << '"';
    for ( itr++; itr < params.end(); itr++ ) {
      o << ',' << '"' << itr->m_Name << '"';
    }
    if ( !outputs.empty() ) {
      o << ',';
    }
  }
  if ( !outputs.empty() ) {
    std::vector<std::string>::const_iterator itr = outputs.begin();
    //std::cout << "Output name: " << *itr << std::endl;
    o << '"' << *itr << '"';
    for ( itr++; itr < outputs.end(); itr++ ) {
      o << ',' << '"' << *itr << '"';
    }
  }
  o << ",\"LogLikelihood\"";
  if( WriteLogLikelihoodGradients ) {
    if ( !outputs.empty() ) {
      for ( std::vector<std::string>::const_iterator itr = outputs.begin();
            itr < outputs.end(); itr++ )
      {
        o << ',' << "\"dLL/d" << *itr << '"';
      }
      for ( std::vector<std::string>::const_iterator itr = outputs.begin();
            itr < outputs.end(); itr++ )
      {
        o << ',' << "\"sigma_" << *itr << "*dLL/dsigma_" << *itr << '"';
      }
    }
  }
  o << "\n";
}

/** Utility for writing a vector to an output stream
 *
 * The vector elements are delimited by the given delimiter */
template <class T>
void write_vector( std::ostream& o, std::vector< T > const & v, char delim ) {
  if ( !v.empty() ) {
    typename std::vector< T >::const_iterator itr = v.begin();
    o << *(itr++);
    while ( itr < v.end() ) {
      o << delim << *(itr++);
    }
  }
}

void
SamplerCSVWriter
::WriteSample( std::ostream & out, const Sample & sample,
            bool WriteLogLikelihoodGradients)
{
  write_vector( out, sample.m_ParameterValues, ',' );
  out << ',';

  if ( sample.m_OutputValues.size() > 0 ) {
    write_vector( out, sample.m_OutputValues, ',' );
    out << ',';
  }
  out << sample.m_LogLikelihood;
  if( WriteLogLikelihoodGradients ) {
    if ( sample.m_OutputValues.size() > 0 ) {
      out << ',';
      write_vector( out, sample.m_LogLikelihoodValueGradient, ',' );
      out << ',';
      write_vector( out, sample.m_LogLikelihoodErrorGradient, ',' );
    }
  }
  if ( sample.m_Comments.size() > 0 ) {
    out << ",\"";
    write_vector( out, sample.m_Comments, ';' );
    out << '"';
  }
  out << '\n';

  out.flush();
}

} // end namespace madai
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */
#include "toolboxcontroller.hxx"
#include <com/sun/star/ui/ImageType.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/menu.hxx>
#include <com/sun/star/ui/XUIConfigurationManager.hpp>
#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
#include <com/sun/star/ui/XImageManager.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/util/Color.hpp>
#include <vcl/svapp.hxx>
#include <vcl/toolbox.hxx>
#include <svtools/miscopt.hxx>
#include <unotools/moduleoptions.hxx>
#include <svtools/menuoptions.hxx>
#include <osl/mutex.hxx>
#include <svx/svxids.hrc>
#define ITEMID_FONT         3
#include <editeng/fontitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <svx/tbcontrl.hxx>
#include <editeng/colritem.hxx>
#include <svx/tbxcustomshapes.hxx>

#include <cppuhelper/supportsservice.hxx>

namespace rptui
{
    using namespace svt;
    using namespace com::sun::star;
    using namespace com::sun::star::uno;
    using namespace com::sun::star::beans;
    using namespace com::sun::star::lang;
    using namespace frame;
    using namespace util;
    using namespace ui;

OUString SAL_CALL OToolboxController::getImplementationName() throw( RuntimeException, std::exception )
{
    return getImplementationName_Static();
}

OUString OToolboxController::getImplementationName_Static() throw( RuntimeException )
{
    return OUString("com.sun.star.report.comp.ReportToolboxController");
}

Sequence< OUString> OToolboxController::getSupportedServiceNames_Static() throw( RuntimeException )
{
    Sequence< OUString> aSupported(1);
    aSupported[0] = "com.sun.star.report.ReportToolboxController";
    return aSupported;
}

sal_Bool SAL_CALL OToolboxController::supportsService( const OUString& ServiceName ) throw (uno::RuntimeException, std::exception)
{
    return cppu::supportsService(this, ServiceName);
}

Sequence< OUString> SAL_CALL OToolboxController::getSupportedServiceNames() throw(RuntimeException, std::exception)
{
    return getSupportedServiceNames_Static();
}

Reference< XInterface > OToolboxController::create(Reference< XComponentContext > const & xContext)
{
    return * new OToolboxController(xContext);
}

OToolboxController::OToolboxController(const Reference< XComponentContext >& _rxORB)
    : m_pToolbarController(NULL)
    ,m_nToolBoxId(1)
    ,m_nSlotId(0)
{
    osl_atomic_increment(&m_refCount);
    m_xContext = _rxORB;
    osl_atomic_decrement(&m_refCount);

}

OToolboxController::~OToolboxController()
{
}

// XInterface
Any SAL_CALL OToolboxController::queryInterface( const Type& _rType ) throw (RuntimeException, std::exception)
{
    Any aReturn = ToolboxController::queryInterface(_rType);
    if (!aReturn.hasValue())
        aReturn = TToolboxController_BASE::queryInterface(_rType);
    return aReturn;
}

void SAL_CALL OToolboxController::acquire() throw ()
{
    ToolboxController::acquire();
}

void SAL_CALL OToolboxController::release() throw ()
{
    ToolboxController::release();
}

void SAL_CALL OToolboxController::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException, std::exception)
{
    ToolboxController::initialize(_rArguments);
    SolarMutexGuard aSolarMutexGuard;
    ::osl::MutexGuard aGuard(m_aMutex);

    VclPtr< ToolBox > pToolBox = static_cast<ToolBox*>(VCLUnoHelper::GetWindow(getParent()).get());
    if ( pToolBox )
    {
        const sal_uInt16 nCount = pToolBox->GetItemCount();
        for (sal_uInt16 nPos = 0; nPos < nCount; ++nPos)
        {
            const sal_uInt16 nItemId = pToolBox->GetItemId(nPos);
            if ( pToolBox->GetItemCommand(nItemId) == m_aCommandURL )
            {
                m_nToolBoxId = nItemId;
                break;
            }
        }
        if ( m_aCommandURL == ".uno:BasicShapes" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:BasicShapes"),sal_True));
            m_pToolbarController = new SvxTbxCtlCustomShapes(m_nSlotId = SID_DRAWTBX_CS_BASIC,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:SymbolShapes" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:SymbolShapes"),sal_True));
            m_pToolbarController = new SvxTbxCtlCustomShapes(m_nSlotId = SID_DRAWTBX_CS_SYMBOL,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:ArrowShapes" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:ArrowShapes"),sal_True));
            m_pToolbarController = new SvxTbxCtlCustomShapes(m_nSlotId = SID_DRAWTBX_CS_ARROW,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:FlowChartShapes" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:FlowChartShapes"),sal_True));
            m_pToolbarController = new SvxTbxCtlCustomShapes(m_nSlotId = SID_DRAWTBX_CS_FLOWCHART,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:CalloutShapes" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:CalloutShapes"),sal_True));
            m_pToolbarController = new SvxTbxCtlCustomShapes(m_nSlotId = SID_DRAWTBX_CS_CALLOUT,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:StarShapes" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:StarShapes"),sal_True));
            m_pToolbarController = new SvxTbxCtlCustomShapes(m_nSlotId = SID_DRAWTBX_CS_STAR,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:CharFontName" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:CharFontName"),sal_True));
            m_pToolbarController = new SvxFontNameToolBoxControl/*SvxStyleToolBoxControl*/(m_nSlotId = SID_ATTR_CHAR_FONT,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:FontColor" || m_aCommandURL == ".uno:Color" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:FontColor"),sal_True));
            m_aStates.insert(TCommandState::value_type(OUString(".uno:Color"),sal_True));
            m_pToolbarController = new SvxColorToolBoxControl(m_nSlotId = SID_ATTR_CHAR_COLOR2,m_nToolBoxId,*pToolBox);
        }
        else
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:BackgroundColor"),sal_True));
            m_pToolbarController = new SvxColorToolBoxControl(m_nSlotId = SID_BACKGROUND_COLOR,m_nToolBoxId,*pToolBox);
        }

        TCommandState::iterator aIter = m_aStates.begin();
        for (; aIter != m_aStates.end(); ++aIter)
            addStatusListener(aIter->first);

        if ( m_pToolbarController.is() )
            m_pToolbarController->initialize(_rArguments);
        // check if paste special is allowed, when not don't add DROPDOWN
        pToolBox->SetItemBits(m_nToolBoxId,pToolBox->GetItemBits(m_nToolBoxId) | ToolBoxItemBits::DROPDOWN);
    }
}

void SAL_CALL OToolboxController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException, std::exception )
{
    ::osl::MutexGuard aGuard(m_aMutex);
    TCommandState::iterator aFind = m_aStates.find( Event.FeatureURL.Complete );
    if ( aFind != m_aStates.end() )
    {
        aFind->second = Event.IsEnabled;
        if ( m_pToolbarController.is() )
        {
            // All other status events will be processed here
            bool bSetCheckmark      = false;
            bool bCheckmark         = false;
            //m_pToolbarController->GetToolBox().Enable(Event.IsEnabled);
            ToolBox& rTb = m_pToolbarController->GetToolBox();
            for ( sal_uInt16 i = 0; i < rTb.GetItemCount(); i++ )
            {
                sal_uInt16 nId = rTb.GetItemId( i );
                if ( nId == 0 )
                    continue;

                OUString aCmd = rTb.GetItemCommand( nId );
                if ( aCmd == Event.FeatureURL.Complete )
                {
                    // Enable/disable item
                    rTb.EnableItem( nId, Event.IsEnabled );

                    // Checkmark
                    if ( Event.State >>= bCheckmark )
                        bSetCheckmark = true;

                    if ( bSetCheckmark )
                        rTb.CheckItem( nId, bCheckmark );
                    else
                    {
                        OUString aItemText;

                        if ( Event.State >>= aItemText )
                            rTb.SetItemText( nId, aItemText );
                    }
                }
            }

            switch(m_nSlotId)
            {
                case SID_ATTR_CHAR_COLOR2:
                case SID_BACKGROUND_COLOR:
                    {
                        util::Color nColor(COL_TRANSPARENT);
                        Event.State >>= nColor;
                        SvxColorItem aColorItem(::Color(nColor), 1);
                        static_cast<SvxColorToolBoxControl*>(m_pToolbarController.get())->StateChanged(m_nSlotId,Event.IsEnabled ? SfxItemState::SET : SfxItemState::DISABLED,&aColorItem);
                    }
                    break;
                case SID_ATTR_CHAR_FONT:
                    {
                        SvxFontItem aItem(ITEMID_FONT);
                        aItem.PutValue(Event.State);
                        static_cast<SvxFontNameToolBoxControl*>(m_pToolbarController.get())->StateChanged(m_nSlotId,Event.IsEnabled ? SfxItemState::DEFAULT : SfxItemState::DISABLED,&aItem);
                    }
                    break;
            }
        }
    }
}

Reference< awt::XWindow > SAL_CALL OToolboxController::createPopupWindow() throw (RuntimeException, std::exception)
{
    // execute the menu
    SolarMutexGuard aSolarMutexGuard;
    ::osl::MutexGuard aGuard(m_aMutex);

    Reference< awt::XWindow > xRet;
    if ( m_pToolbarController.is() )
        xRet = m_pToolbarController->createPopupWindow();

    return xRet;
}

void SAL_CALL OToolboxController::execute( sal_Int16 KeyModifier ) throw (uno::RuntimeException, std::exception)
{
    if ( m_pToolbarController.is() )
        m_pToolbarController->execute( KeyModifier );
}

sal_Bool SAL_CALL OToolboxController::opensSubToolbar() throw (uno::RuntimeException, std::exception)
{
    return ( m_nSlotId == SID_DRAWTBX_CS_BASIC ||
             m_nSlotId == SID_DRAWTBX_CS_SYMBOL ||
             m_nSlotId == SID_DRAWTBX_CS_ARROW ||
             m_nSlotId == SID_DRAWTBX_CS_FLOWCHART ||
             m_nSlotId == SID_DRAWTBX_CS_CALLOUT ||
             m_nSlotId == SID_DRAWTBX_CS_STAR );
}

OUString SAL_CALL OToolboxController::getSubToolbarName() throw (uno::RuntimeException, std::exception)
{
    SolarMutexGuard aSolarMutexGuard;
    ::osl::MutexGuard aGuard(m_aMutex);
    if ( m_pToolbarController.is() )
        return m_pToolbarController->getSubToolbarName();
    return OUString();
}

void SAL_CALL OToolboxController::functionSelected( const OUString& rCommand ) throw (uno::RuntimeException, std::exception)
{
    SolarMutexGuard aSolarMutexGuard;
    ::osl::MutexGuard aGuard(m_aMutex);
    if ( m_pToolbarController.is() )
    {
        m_pToolbarController->functionSelected(m_aCommandURL = rCommand);
    }
}

void SAL_CALL OToolboxController::updateImage(  ) throw (uno::RuntimeException, std::exception)
{
    SolarMutexGuard aSolarMutexGuard;
    ::osl::MutexGuard aGuard(m_aMutex);
    if ( m_pToolbarController.is() )
        m_pToolbarController->updateImage();
}

uno::Reference< awt::XWindow > SAL_CALL OToolboxController::createItemWindow( const uno::Reference< awt::XWindow >& _xParent)
throw (uno::RuntimeException, std::exception)
{
    uno::Reference< awt::XWindow > xWindow;
    if ( m_pToolbarController.is() )
    {
        switch(m_nSlotId)
        {
            case SID_ATTR_CHAR_FONT:
                xWindow = VCLUnoHelper::GetInterface(static_cast<SvxFontNameToolBoxControl*>(m_pToolbarController.get())->CreateItemWindow(VCLUnoHelper::GetWindow(_xParent)));
                break;
            default:
                ;
        }
    }
    return xWindow;
}

} // rptui

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>tdf#83541 Fix also for reportdesign<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */
#include "toolboxcontroller.hxx"
#include <com/sun/star/ui/ImageType.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/menu.hxx>
#include <com/sun/star/ui/XUIConfigurationManager.hpp>
#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
#include <com/sun/star/ui/XImageManager.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/util/Color.hpp>
#include <vcl/svapp.hxx>
#include <vcl/toolbox.hxx>
#include <svtools/miscopt.hxx>
#include <unotools/moduleoptions.hxx>
#include <svtools/menuoptions.hxx>
#include <osl/mutex.hxx>
#include <svx/svxids.hrc>
#define ITEMID_FONT         3
#include <editeng/fontitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <svx/tbcontrl.hxx>
#include <editeng/colritem.hxx>
#include <svx/tbxcustomshapes.hxx>

#include <cppuhelper/supportsservice.hxx>

namespace rptui
{
    using namespace svt;
    using namespace com::sun::star;
    using namespace com::sun::star::uno;
    using namespace com::sun::star::beans;
    using namespace com::sun::star::lang;
    using namespace frame;
    using namespace util;
    using namespace ui;

OUString SAL_CALL OToolboxController::getImplementationName() throw( RuntimeException, std::exception )
{
    return getImplementationName_Static();
}

OUString OToolboxController::getImplementationName_Static() throw( RuntimeException )
{
    return OUString("com.sun.star.report.comp.ReportToolboxController");
}

Sequence< OUString> OToolboxController::getSupportedServiceNames_Static() throw( RuntimeException )
{
    Sequence< OUString> aSupported(1);
    aSupported[0] = "com.sun.star.report.ReportToolboxController";
    return aSupported;
}

sal_Bool SAL_CALL OToolboxController::supportsService( const OUString& ServiceName ) throw (uno::RuntimeException, std::exception)
{
    return cppu::supportsService(this, ServiceName);
}

Sequence< OUString> SAL_CALL OToolboxController::getSupportedServiceNames() throw(RuntimeException, std::exception)
{
    return getSupportedServiceNames_Static();
}

Reference< XInterface > OToolboxController::create(Reference< XComponentContext > const & xContext)
{
    return * new OToolboxController(xContext);
}

OToolboxController::OToolboxController(const Reference< XComponentContext >& _rxORB)
    : m_pToolbarController(NULL)
    ,m_nToolBoxId(1)
    ,m_nSlotId(0)
{
    osl_atomic_increment(&m_refCount);
    m_xContext = _rxORB;
    osl_atomic_decrement(&m_refCount);

}

OToolboxController::~OToolboxController()
{
}

// XInterface
Any SAL_CALL OToolboxController::queryInterface( const Type& _rType ) throw (RuntimeException, std::exception)
{
    Any aReturn = ToolboxController::queryInterface(_rType);
    if (!aReturn.hasValue())
        aReturn = TToolboxController_BASE::queryInterface(_rType);
    return aReturn;
}

void SAL_CALL OToolboxController::acquire() throw ()
{
    ToolboxController::acquire();
}

void SAL_CALL OToolboxController::release() throw ()
{
    ToolboxController::release();
}

void SAL_CALL OToolboxController::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException, std::exception)
{
    ToolboxController::initialize(_rArguments);
    SolarMutexGuard aSolarMutexGuard;
    ::osl::MutexGuard aGuard(m_aMutex);

    VclPtr< ToolBox > pToolBox = static_cast<ToolBox*>(VCLUnoHelper::GetWindow(getParent()).get());
    if ( pToolBox )
    {
        const sal_uInt16 nCount = pToolBox->GetItemCount();
        for (sal_uInt16 nPos = 0; nPos < nCount; ++nPos)
        {
            const sal_uInt16 nItemId = pToolBox->GetItemId(nPos);
            if ( pToolBox->GetItemCommand(nItemId) == m_aCommandURL )
            {
                m_nToolBoxId = nItemId;
                break;
            }
        }
        if ( m_aCommandURL == ".uno:BasicShapes" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:BasicShapes"),sal_True));
            m_pToolbarController = new SvxTbxCtlCustomShapes(m_nSlotId = SID_DRAWTBX_CS_BASIC,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:SymbolShapes" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:SymbolShapes"),sal_True));
            m_pToolbarController = new SvxTbxCtlCustomShapes(m_nSlotId = SID_DRAWTBX_CS_SYMBOL,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:ArrowShapes" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:ArrowShapes"),sal_True));
            m_pToolbarController = new SvxTbxCtlCustomShapes(m_nSlotId = SID_DRAWTBX_CS_ARROW,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:FlowChartShapes" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:FlowChartShapes"),sal_True));
            m_pToolbarController = new SvxTbxCtlCustomShapes(m_nSlotId = SID_DRAWTBX_CS_FLOWCHART,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:CalloutShapes" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:CalloutShapes"),sal_True));
            m_pToolbarController = new SvxTbxCtlCustomShapes(m_nSlotId = SID_DRAWTBX_CS_CALLOUT,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:StarShapes" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:StarShapes"),sal_True));
            m_pToolbarController = new SvxTbxCtlCustomShapes(m_nSlotId = SID_DRAWTBX_CS_STAR,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:CharFontName" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:CharFontName"),sal_True));
            m_pToolbarController = new SvxFontNameToolBoxControl/*SvxStyleToolBoxControl*/(m_nSlotId = SID_ATTR_CHAR_FONT,m_nToolBoxId,*pToolBox);
        }
        else if ( m_aCommandURL == ".uno:FontColor" || m_aCommandURL == ".uno:Color" )
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:FontColor"),sal_True));
            m_aStates.insert(TCommandState::value_type(OUString(".uno:Color"),sal_True));
            m_pToolbarController = new SvxColorToolBoxControl(m_nSlotId = SID_ATTR_CHAR_COLOR2,m_nToolBoxId,*pToolBox);
        }
        else
        {
            m_aStates.insert(TCommandState::value_type(OUString(".uno:BackgroundColor"),sal_True));
            m_pToolbarController = new SvxColorToolBoxControl(m_nSlotId = SID_BACKGROUND_COLOR,m_nToolBoxId,*pToolBox);
        }

        TCommandState::iterator aIter = m_aStates.begin();
        for (; aIter != m_aStates.end(); ++aIter)
            addStatusListener(aIter->first);

        if ( m_pToolbarController.is() )
            m_pToolbarController->initialize(_rArguments);
        // check if paste special is allowed, when not don't add DROPDOWN
        pToolBox->SetItemBits(m_nToolBoxId,pToolBox->GetItemBits(m_nToolBoxId) | ToolBoxItemBits::DROPDOWN);
    }
}

void SAL_CALL OToolboxController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException, std::exception )
{
    ::osl::MutexGuard aGuard(m_aMutex);
    TCommandState::iterator aFind = m_aStates.find( Event.FeatureURL.Complete );
    if ( aFind != m_aStates.end() )
    {
        aFind->second = Event.IsEnabled;
        if ( m_pToolbarController.is() )
        {
            // All other status events will be processed here
            bool bSetCheckmark      = false;
            bool bCheckmark         = false;
            //m_pToolbarController->GetToolBox().Enable(Event.IsEnabled);
            ToolBox& rTb = m_pToolbarController->GetToolBox();
            for ( sal_uInt16 i = 0; i < rTb.GetItemCount(); i++ )
            {
                sal_uInt16 nId = rTb.GetItemId( i );
                if ( nId == 0 )
                    continue;

                OUString aCmd = rTb.GetItemCommand( nId );
                if ( aCmd == Event.FeatureURL.Complete )
                {
                    // Enable/disable item
                    rTb.EnableItem( nId, Event.IsEnabled );

                    // Checkmark
                    if ( Event.State >>= bCheckmark )
                        bSetCheckmark = true;

                    if ( bSetCheckmark )
                        rTb.CheckItem( nId, bCheckmark );
                    else
                    {
                        OUString aItemText;

                        if ( Event.State >>= aItemText )
                            rTb.SetItemText( nId, aItemText );
                    }
                }
            }

            switch(m_nSlotId)
            {
                case SID_ATTR_CHAR_COLOR2:
                case SID_BACKGROUND_COLOR:
                    {
                        util::Color nColor(COL_TRANSPARENT);
                        Event.State >>= nColor;
                        SvxColorItem aColorItem(::Color(nColor), 1);
                        static_cast<SvxColorToolBoxControl*>(m_pToolbarController.get())->StateChanged(m_nSlotId,Event.IsEnabled ? SfxItemState::SET : SfxItemState::DISABLED,&aColorItem);
                    }
                    break;
                case SID_ATTR_CHAR_FONT:
                    {
                        SvxFontItem aItem(ITEMID_FONT);
                        aItem.PutValue(Event.State);
                        static_cast<SvxFontNameToolBoxControl*>(m_pToolbarController.get())->StateChanged(m_nSlotId,Event.IsEnabled ? SfxItemState::DEFAULT : SfxItemState::DISABLED,&aItem);
                    }
                    break;
            }
        }
    }
}

Reference< awt::XWindow > SAL_CALL OToolboxController::createPopupWindow() throw (RuntimeException, std::exception)
{
    // execute the menu
    SolarMutexGuard aSolarMutexGuard;
    ::osl::MutexGuard aGuard(m_aMutex);

    Reference< awt::XWindow > xRet;
    if ( m_pToolbarController.is() )
        xRet = m_pToolbarController->createPopupWindow();

    return xRet;
}

void SAL_CALL OToolboxController::execute( sal_Int16 KeyModifier ) throw (uno::RuntimeException, std::exception)
{
    if ( m_pToolbarController.is() )
        m_pToolbarController->execute( KeyModifier );
}

sal_Bool SAL_CALL OToolboxController::opensSubToolbar() throw (uno::RuntimeException, std::exception)
{
    return ( m_nSlotId != SID_ATTR_CHAR_FONT );
}

OUString SAL_CALL OToolboxController::getSubToolbarName() throw (uno::RuntimeException, std::exception)
{
    SolarMutexGuard aSolarMutexGuard;
    ::osl::MutexGuard aGuard(m_aMutex);
    if ( m_pToolbarController.is() )
        return m_pToolbarController->getSubToolbarName();
    return OUString();
}

void SAL_CALL OToolboxController::functionSelected( const OUString& rCommand ) throw (uno::RuntimeException, std::exception)
{
    SolarMutexGuard aSolarMutexGuard;
    ::osl::MutexGuard aGuard(m_aMutex);
    if ( m_pToolbarController.is() )
    {
        m_pToolbarController->functionSelected(m_aCommandURL = rCommand);
    }
}

void SAL_CALL OToolboxController::updateImage(  ) throw (uno::RuntimeException, std::exception)
{
    SolarMutexGuard aSolarMutexGuard;
    ::osl::MutexGuard aGuard(m_aMutex);
    if ( m_pToolbarController.is() )
        m_pToolbarController->updateImage();
}

uno::Reference< awt::XWindow > SAL_CALL OToolboxController::createItemWindow( const uno::Reference< awt::XWindow >& _xParent)
throw (uno::RuntimeException, std::exception)
{
    uno::Reference< awt::XWindow > xWindow;
    if ( m_pToolbarController.is() )
    {
        switch(m_nSlotId)
        {
            case SID_ATTR_CHAR_FONT:
                xWindow = VCLUnoHelper::GetInterface(static_cast<SvxFontNameToolBoxControl*>(m_pToolbarController.get())->CreateItemWindow(VCLUnoHelper::GetWindow(_xParent)));
                break;
            default:
                ;
        }
    }
    return xWindow;
}

} // rptui

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>