<commit_before>/*
  ==============================================================================

    ShutterAnimator.cpp
    Created: 4 May 2015 10:40:25pm
    Author:  Adam Elemental

  ==============================================================================
*/

ShutterAnimator::ShutterAnimator (Rectangle<int> focusArea)
    :   StackAnimator(),
        focusArea (focusArea),
        slideDuration (150),
        startSpeed (1.0),
        endSpeed (1.0)
{
    Desktop::getInstance().getAnimator().addChangeListener (this);
}

ShutterAnimator::ShutterAnimator (Rectangle<int> focusArea, int slideDuration, float startSpeed, float endSpeed)
    :   StackAnimator(),
        focusArea (focusArea),
        slideDuration (slideDuration),
        startSpeed (startSpeed),
        endSpeed (endSpeed)
{
    Desktop::getInstance().getAnimator().addChangeListener (this);
}

ShutterAnimator::ShutterAnimator ()
    :   StackAnimator(),
        slideDuration (150),
        startSpeed (1.0),
        endSpeed (1.0)
{
    Desktop::getInstance().getAnimator().addChangeListener (this);
}

ShutterAnimator::ShutterAnimator (int slideDuration, float startSpeed, float endSpeed)
    :   StackAnimator(),
        slideDuration (slideDuration),
        startSpeed (startSpeed),
        endSpeed (endSpeed)
{
    Desktop::getInstance().getAnimator().addChangeListener (this);
}

ShutterAnimator::~ShutterAnimator ()
{
    topSnapshot = nullptr;
    bottomSnapshot = nullptr;
    focusSnapshot = nullptr;
    deletedPanel = nullptr;
    previousPanel.deleteAndZero();
}
void ShutterAnimator::setFocusArea (Rectangle<int> newFocusArea)
{
    focusArea = newFocusArea;
}

void ShutterAnimator::refreshLayout ()
{
    for (int i = 0; i < stackComponent->getStackSize (); i++)
    {
        Component* panel = stackComponent->getContentComponentAtIndex (i);
        if (i == stackComponent->getStackFocusIndex())
        {
            panel->setVisible (true);
            panel->setBounds (0, 0, stackComponent->getWidth(), stackComponent->getHeight());
        }
        else
        {
            panel->setVisible (false);
        }
    }
}

void ShutterAnimator::animateContentComponentAdded (Component *newContent, int index)
{

}

/**
 * save the image of the deleted component and display that
 * so that the animation can play on top of it
 */
void ShutterAnimator::animateContentComponentRemoved (Component* contentRemoved, int index)
{
    Rectangle<int> bounds = getCurrentBounds();
    // save deleted content image
    deletedPanel = new ImageComponent("Deleted Panel Snapshot");
    Image contentRemovedImage = contentRemoved->createComponentSnapshot (contentRemoved->getLocalBounds(), false);

    deletedPanel->setImage (contentRemovedImage);

    stackComponent->addAndMakeVisible (deletedPanel);
    deletedPanel->setBounds (bounds);

    if (previousPanel.getComponent() != nullptr)
    {
        // put deletedPanel behind animations
        deletedPanel->toBehind(previousPanel);
        previousPanel->setVisible (false);
    }
    else
    {
        deletedPanel->toBack();
    }
}

void ShutterAnimator::animateStackFocusChange (Component* newFocusContent, int newIndex, int oldIndex)
{
    jassert (stackComponent != nullptr);
    Component* panel;

    Rectangle<int> bounds = getCurrentBounds();
    isOpening = newIndex > oldIndex;

    // Split the old panel in two (one above, one below the focusArea)
    // Take a snapshot of each
    // Put the resulting Images into an ImageComponent
    // Animate the ImageComponents to move up and down
    panel = stackComponent->getContentComponentAtIndex (isOpening ? oldIndex : newIndex);
    if (panel != 0)
    {
        // TODO: Tidy this code up - work out whats going with the focusArea adjustments

        Rectangle<int> topBounds (0, 0, bounds.getWidth(), focusArea.getY());
        topSnapshot = new ImageComponent("Top Snapshot");
        topSnapshot->setImage (panel->createComponentSnapshot (topBounds));

        int bottomY = focusArea.getY()+focusArea.getHeight();
        DBG ("bottomY " << bottomY);
        Rectangle<int> bottomBounds (0, bottomY, bounds.getWidth(), bounds.getHeight() );
        bottomSnapshot = new ImageComponent("Bottom Snapshot");
        bottomSnapshot->setImage (panel->createComponentSnapshot (bottomBounds));

        focusSnapshot = new ImageComponent("Focus Snapshot");
        DBG (focusArea.toString());
        Rectangle<int> actualFocusArea (0, focusArea.getY(), bounds.getWidth(), focusArea.getHeight());
        focusSnapshot->setImage (panel->createComponentSnapshot (actualFocusArea));

        stackComponent->addAndMakeVisible (topSnapshot);
        if (! isOpening) topBounds.setY (0-topBounds.getHeight());
        topSnapshot->setBounds (topBounds);

        stackComponent->addAndMakeVisible (bottomSnapshot);
        bottomBounds.setTop (focusArea.getHeight());
        if (! isOpening) bottomBounds.setY (bottomBounds.getHeight());
        bottomSnapshot->setBounds (bottomBounds);

        stackComponent->addChildComponent (focusSnapshot);
        focusSnapshot->setBounds (actualFocusArea);
        if (isOpening)
        {
            focusSnapshot->setVisible (true);
            Desktop::getInstance().getAnimator().fadeOut (focusSnapshot, slideDuration);
        }
        else
        {
            Desktop::getInstance().getAnimator().fadeIn (focusSnapshot, slideDuration);
        }

        // TODO - check for largest distance and use that for both up and down animations

        if (isOpening) topBounds.setY (0-topBounds.getHeight());
        else topBounds.setY (0);
        Desktop::getInstance().getAnimator().animateComponent(topSnapshot, topBounds, 1.0f, slideDuration, true, startSpeed, endSpeed);

        if (isOpening) bottomBounds.setY (bottomBounds.getHeight());
        else bottomBounds.setY (focusArea.getY() + focusArea.getHeight());
        DBG ("bottomBounds.getY: " << bottomBounds.getY());
        Desktop::getInstance().getAnimator().animateComponent(bottomSnapshot, bottomBounds, 1.0f, slideDuration, true, startSpeed, endSpeed);
    }

    if (isOpening)
    {
        panel = stackComponent->getContentComponentAtIndex (newIndex);
        if (panel != 0)
        {
            panel->setVisible (true);
            panel->setBounds (bounds);
            previousPanel = nullptr;
        }
    }
    else
    {
        previousPanel = stackComponent->getContentComponentAtIndex (newIndex);

        if (previousPanel.getComponent() != nullptr)
        {
            previousPanel->setVisible (false);
        }

        panel = stackComponent->getContentComponentAtIndex (oldIndex);
        if (panel != nullptr)
        {
            panel->setVisible (true);  // try and take this out to fix bug on close
        }
    }
}

void ShutterAnimator::setDuration (int durationMs, double newStartSpeed, double newEndSpeed)
{
    slideDuration = durationMs;
    startSpeed = newStartSpeed;
    endSpeed = newEndSpeed;
}

/**
 * Check if we've finished an animation and remove the proxy image components
 * plus other stuff to make it work both for back button and breadcrumb navigation
 */
void ShutterAnimator::changeListenerCallback (ChangeBroadcaster *source)
{
    DBG ("topSnapshot->getHeight " << topSnapshot->getHeight());

    if (isOpening)
    {
        if ((! Desktop::getInstance().getAnimator().isAnimating (topSnapshot) && topSnapshot->getBottom() <= 0)
        && (! Desktop::getInstance().getAnimator().isAnimating (bottomSnapshot) && bottomSnapshot->getY() >= stackComponent->getHeight()))
        {
            finishedAnimating = true;
        }
    }
    else
    {
        DBG ("topSnapshot.getY " << topSnapshot->getY());
        DBG ("bottomSnapshot.getY " << bottomSnapshot->getY() << ", focusSnapshot->getBottom() ==" << focusSnapshot->getBottom());
        if ((! Desktop::getInstance().getAnimator().isAnimating (topSnapshot) && topSnapshot->getY() >= 0)
        && (! Desktop::getInstance().getAnimator().isAnimating (bottomSnapshot) && bottomSnapshot->getY() <= focusSnapshot->getBottom()))
        {
            finishedAnimating = true;
        }
    }

    if (finishedAnimating)
    {

        DBG ("finishedAnimating: " << (isOpening ? "opening" : "closing"));
        topSnapshot->setVisible (false);
        bottomSnapshot->setVisible (false);
        focusSnapshot->setVisible (false);

        DBG ("removed snapshots");

        if (deletedPanel != nullptr)
        {
            deletedPanel->setVisible (false);
            deletedPanel = nullptr;
            DBG ("remove deletedPanel");
        }
        if (previousPanel.getComponent() != nullptr && !previousPanel->isShowing())
        {
            DBG ("Show previousPanel");
            previousPanel->setVisible (true);
            int currentIndex = stackComponent->indexOfContentComponent(previousPanel.getComponent());
            DBG ("Index: " << currentIndex << ", size: " << stackComponent->getStackSize());

            if (currentIndex < stackComponent->getStackSize()-1)
            {
                // hide next component if were going backwards and not deleted the last component
                stackComponent->getContentComponentAtIndex (currentIndex + 1)->setVisible (false);
            }
        }
        previousPanel = nullptr;

        finishedAnimating = false;
    }

}

/**
 * Get current bounds for the StackComponent
 */
Rectangle<int> ShutterAnimator::getCurrentBounds() const
{
    int w = stackComponent->getWidth();
    int h = stackComponent->getHeight();
    return Rectangle<int> (0, 0, w, h);
}

<commit_msg>implement equal velocity<commit_after>/*
  ==============================================================================

    ShutterAnimator.cpp
    Created: 4 May 2015 10:40:25pm
    Author:  Adam Elemental

  ==============================================================================
*/

ShutterAnimator::ShutterAnimator (Rectangle<int> focusArea)
    :   StackAnimator(),
        focusArea (focusArea),
        slideDuration (150),
        startSpeed (1.0),
        endSpeed (1.0)
{
    Desktop::getInstance().getAnimator().addChangeListener (this);
}

ShutterAnimator::ShutterAnimator (Rectangle<int> focusArea, int slideDuration, float startSpeed, float endSpeed)
    :   StackAnimator(),
        focusArea (focusArea),
        slideDuration (slideDuration),
        startSpeed (startSpeed),
        endSpeed (endSpeed)
{
    Desktop::getInstance().getAnimator().addChangeListener (this);
}

ShutterAnimator::ShutterAnimator ()
    :   StackAnimator(),
        slideDuration (150),
        startSpeed (1.0),
        endSpeed (1.0)
{
    Desktop::getInstance().getAnimator().addChangeListener (this);
}

ShutterAnimator::ShutterAnimator (int slideDuration, float startSpeed, float endSpeed)
    :   StackAnimator(),
        slideDuration (slideDuration),
        startSpeed (startSpeed),
        endSpeed (endSpeed)
{
    Desktop::getInstance().getAnimator().addChangeListener (this);
}

ShutterAnimator::~ShutterAnimator ()
{
    topSnapshot = nullptr;
    bottomSnapshot = nullptr;
    focusSnapshot = nullptr;
    deletedPanel = nullptr;
    previousPanel.deleteAndZero();
}
void ShutterAnimator::setFocusArea (Rectangle<int> newFocusArea)
{
    focusArea = newFocusArea;
}

void ShutterAnimator::refreshLayout ()
{
    for (int i = 0; i < stackComponent->getStackSize (); i++)
    {
        Component* panel = stackComponent->getContentComponentAtIndex (i);
        if (i == stackComponent->getStackFocusIndex())
        {
            panel->setVisible (true);
            panel->setBounds (0, 0, stackComponent->getWidth(), stackComponent->getHeight());
        }
        else
        {
            panel->setVisible (false);
        }
    }
}

void ShutterAnimator::animateContentComponentAdded (Component *newContent, int index)
{

}

/**
 * save the image of the deleted component and display that
 * so that the animation can play on top of it
 */
void ShutterAnimator::animateContentComponentRemoved (Component* contentRemoved, int index)
{
    Rectangle<int> bounds = getCurrentBounds();
    // save deleted content image
    deletedPanel = new ImageComponent("Deleted Panel Snapshot");
    Image contentRemovedImage = contentRemoved->createComponentSnapshot (contentRemoved->getLocalBounds(), false);

    deletedPanel->setImage (contentRemovedImage);

    stackComponent->addAndMakeVisible (deletedPanel);
    deletedPanel->setBounds (bounds);

    if (previousPanel.getComponent() != nullptr)
    {
        // put deletedPanel behind animations
        deletedPanel->toBehind(previousPanel);
        previousPanel->setVisible (false);
    }
    else
    {
        deletedPanel->toBack();
    }
}

void ShutterAnimator::animateStackFocusChange (Component* newFocusContent, int newIndex, int oldIndex)
{
    jassert (stackComponent != nullptr);
    Component* panel;

    Rectangle<int> bounds = getCurrentBounds();
    isOpening = newIndex > oldIndex;

    // Split the old panel in two (one above, one below the focusArea)
    // Take a snapshot of each
    // Put the resulting Images into an ImageComponent
    // Animate the ImageComponents to move up and down
    panel = stackComponent->getContentComponentAtIndex (isOpening ? oldIndex : newIndex);
    if (panel != 0)
    {
        // TODO: Tidy this code up - work out whats going with the focusArea adjustments

        Rectangle<int> topBounds (0, 0, bounds.getWidth(), focusArea.getY());
        topSnapshot = new ImageComponent("Top Snapshot");
        topSnapshot->setImage (panel->createComponentSnapshot (topBounds));

        int bottomY = focusArea.getY()+focusArea.getHeight();
        DBG ("bottomY " << bottomY);
        Rectangle<int> bottomBounds (0, bottomY, bounds.getWidth(), bounds.getHeight() );
        bottomSnapshot = new ImageComponent("Bottom Snapshot");
        bottomSnapshot->setImage (panel->createComponentSnapshot (bottomBounds));

        focusSnapshot = new ImageComponent("Focus Snapshot");
        DBG (focusArea.toString());
        Rectangle<int> actualFocusArea (0, focusArea.getY(), bounds.getWidth(), focusArea.getHeight());
        focusSnapshot->setImage (panel->createComponentSnapshot (actualFocusArea));

        // check for largest distance and use that for both up and down animations to keep same velocity
        int largestHeight = (topBounds.getHeight() > bottomBounds.getHeight() ? topBounds.getHeight() : bottomBounds.getHeight());

        stackComponent->addAndMakeVisible (topSnapshot);
        if (! isOpening) topBounds.setY (0-largestHeight);
        topSnapshot->setBounds (topBounds);

        stackComponent->addAndMakeVisible (bottomSnapshot);
        bottomBounds.setTop (focusArea.getHeight());
        if (! isOpening) bottomBounds.setY (largestHeight);
        bottomSnapshot->setBounds (bottomBounds);

        stackComponent->addChildComponent (focusSnapshot);
        focusSnapshot->setBounds (actualFocusArea);
        if (isOpening)
        {
            focusSnapshot->setVisible (true);
            Desktop::getInstance().getAnimator().fadeOut (focusSnapshot, slideDuration);
        }
        else
        {
            Desktop::getInstance().getAnimator().fadeIn (focusSnapshot, slideDuration);
        }

        if (isOpening) topBounds.setY (0-largestHeight);
        else topBounds.setY (0);
        Desktop::getInstance().getAnimator().animateComponent(topSnapshot, topBounds, 1.0f, slideDuration, true, startSpeed, endSpeed);

        if (isOpening) bottomBounds.setY (largestHeight);
        else bottomBounds.setY (focusArea.getY() + focusArea.getHeight());
        DBG ("bottomBounds.getY: " << bottomBounds.getY());
        Desktop::getInstance().getAnimator().animateComponent(bottomSnapshot, bottomBounds, 1.0f, slideDuration, true, startSpeed, endSpeed);
    }

    if (isOpening)
    {
        panel = stackComponent->getContentComponentAtIndex (newIndex);
        if (panel != 0)
        {
            panel->setVisible (true);
            panel->setBounds (bounds);
            previousPanel = nullptr;
        }
    }
    else
    {
        previousPanel = stackComponent->getContentComponentAtIndex (newIndex);

        if (previousPanel.getComponent() != nullptr)
        {
            previousPanel->setVisible (false);
        }

        panel = stackComponent->getContentComponentAtIndex (oldIndex);
        if (panel != nullptr)
        {
            panel->setVisible (true);  // try and take this out to fix bug on close
        }
    }
}

void ShutterAnimator::setDuration (int durationMs, double newStartSpeed, double newEndSpeed)
{
    slideDuration = durationMs;
    startSpeed = newStartSpeed;
    endSpeed = newEndSpeed;
}

/**
 * Check if we've finished an animation and remove the proxy image components
 * plus other stuff to make it work both for back button and breadcrumb navigation
 */
void ShutterAnimator::changeListenerCallback (ChangeBroadcaster *source)
{
    DBG ("topSnapshot->getHeight " << topSnapshot->getHeight());

    if (isOpening)
    {
        if ((! Desktop::getInstance().getAnimator().isAnimating (topSnapshot) && topSnapshot->getBottom() <= 0)
        && (! Desktop::getInstance().getAnimator().isAnimating (bottomSnapshot) && bottomSnapshot->getY() >= stackComponent->getHeight()))
        {
            finishedAnimating = true;
        }
    }
    else
    {
        DBG ("topSnapshot.getY " << topSnapshot->getY());
        DBG ("bottomSnapshot.getY " << bottomSnapshot->getY() << ", focusSnapshot->getBottom() ==" << focusSnapshot->getBottom());
        if ((! Desktop::getInstance().getAnimator().isAnimating (topSnapshot) && topSnapshot->getY() == 0)
        && (! Desktop::getInstance().getAnimator().isAnimating (bottomSnapshot) && bottomSnapshot->getY() == focusSnapshot->getBottom()))
        {
            finishedAnimating = true;
        }
    }

    if (finishedAnimating)
    {

        DBG ("finishedAnimating: " << (isOpening ? "opening" : "closing"));
        topSnapshot->setVisible (false);
        bottomSnapshot->setVisible (false);
        focusSnapshot->setVisible (false);

        DBG ("removed snapshots");

        if (deletedPanel != nullptr)
        {
            deletedPanel->setVisible (false);
            deletedPanel = nullptr;
            DBG ("remove deletedPanel");
        }
        if (previousPanel.getComponent() != nullptr && !previousPanel->isShowing())
        {
            DBG ("Show previousPanel");
            previousPanel->setVisible (true);
            int currentIndex = stackComponent->indexOfContentComponent(previousPanel.getComponent());
            DBG ("Index: " << currentIndex << ", size: " << stackComponent->getStackSize());

            if (currentIndex < stackComponent->getStackSize()-1)
            {
                // hide next component if were going backwards and not deleted the last component
                stackComponent->getContentComponentAtIndex (currentIndex + 1)->setVisible (false);
            }
        }
        previousPanel = nullptr;

        finishedAnimating = false;
    }

}

/**
 * Get current bounds for the StackComponent
 */
Rectangle<int> ShutterAnimator::getCurrentBounds() const
{
    int w = stackComponent->getWidth();
    int h = stackComponent->getHeight();
    return Rectangle<int> (0, 0, w, h);
}

<|endoftext|>


<commit_before>#include <cetty/zurg/slave/SlaveServiceImpl.h>

#include <boost/weak_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <cetty/util/SmallFile.h>
#include <cetty/config/ConfigCenter.h>
#include <cetty/logging/LoggerHelper.h>
#include <cetty/channel/EventLoopPool.h>

#include <cetty/zurg/Util.h>
#include <cetty/zurg/slave/Process.h>
#include <cetty/zurg/slave/ApplicationManager.h>
#include <cetty/zurg/slave/ProcessManager.h>
#include <cetty/zurg/slave/GetHardwareTask.h>

namespace cetty {
namespace zurg {
namespace slave {

using namespace cetty::zurg;
using namespace cetty::util;
using namespace cetty::channel;
using namespace cetty::config;

SlaveServiceImpl::SlaveServiceImpl(const EventLoopPtr& loop) {
    ConfigCenter::instance().configure(&config_);
    processManager_.reset(new ProcessManager(loop));
    applicationManager_.reset(new ApplicationManager(processManager_.get()));

    // start all configured applications
    init();
}

SlaveServiceImpl::~SlaveServiceImpl() {

}

void SlaveServiceImpl::getHardware(const ConstGetHardwareRequestPtr& request,
                                   const GetHardwareResponsePtr& response,
                                   const DoneCallback& done) {

    LOG_INFO << "SlaveServiceImpl::getHardware - lshw = "
             << request->lshw();

    GetHardwareTaskPtr task(new GetHardwareTask(request, response, done, *this));
}

void SlaveServiceImpl::getFileContent(const ConstGetFileContentRequestPtr& request,
                                      const GetFileContentResponsePtr& response,
                                      const DoneCallback& done) {

    LOG_INFO << "SlaveServiceImpl::getFileContent - " << request->file_name()
             << " maxSize = " << request->max_size();

    int64_t file_size = 0;
    int64_t modify_time = 0;
    int64_t create_time = 0;
    int err = SmallFile::readFile(request->file_name(),
                                  request->max_size(),
                                  response->mutable_content(),
                                  &file_size,
                                  &modify_time,
                                  &create_time);
    response->set_error_code(err);
    response->set_file_size(file_size);
    response->set_modify_time(modify_time);
    response->set_create_time(create_time);

    LOG_DEBUG << "SlaveServiceImpl::getFileContent - err " << err;
    done(response);
}

void SlaveServiceImpl::getFileChecksum(const ConstGetFileChecksumRequestPtr& request,
                                       const GetFileChecksumResponsePtr& response,
                                       const DoneCallback& done) {

    DLOG_DEBUG ;

    if (request->files_size() > 0) {
        RunCommandRequestPtr runCommandReq(new RunCommandRequest);
        runCommandReq->set_command("md5sum");

        for (int i = 0; i < request->files_size(); ++i) {
            assert(request->files(i).find('\n') == std::string::npos);
            runCommandReq->add_args(request->files(i));
        }

        runCommand(
            runCommandReq,
            NULL,
            boost::bind(&SlaveServiceImpl::getFileChecksumDone,
                        this, request, _1, done)
        );
    }
    else {
        GetFileChecksumResponse response;
        done(&response);
    }
}

void SlaveServiceImpl::getFileChecksumDone(const ConstGetFileChecksumRequestPtr& request,
        const google::protobuf::Message* message,
        const DoneCallback& done) {

    const RunCommandResponse* runCommandResp =
        google::protobuf::down_cast<const RunCommandResponse*>(message);

    const std::string& lines = runCommandResp->std_output();
    std::map<StringPiece, StringPiece> md5sums;
    parseMd5sum(lines, &md5sums);

    GetFileChecksumResponse response;

    for (int i = 0; i < request->files_size(); ++i) {
        md5sums[request->files(i)].copy_to(response.add_md5sums());
    }

    done(&response);
}

void SlaveServiceImpl::runCommand(const ConstRunCommandRequestPtr& request,
                                  const RunCommandResponsePtr& response,
                                  const DoneCallback& done) {

    LOG_INFO << "SlaveServiceImpl::runCommand - " << request->command();

    ProcessPtr process(new Process(request, response, done, true, true,
                                   config_.slaveName,
                                   config_.prefix));

    int err = 12; // ENOMEM;

    try {
        err = process->start();
    }
    catch (...) {}

    if (err) {
        response->set_error_code(err);
        done(response);
    }
    else {
        processManager_->runAtExit(
            process->pid(),  // bind strong ptr
            boost::bind(&Process::onCommandExit,
                        process, _1, _2)
        );

        EventLoopPtr elp = EventLoopPool::current();
        assert(elp);
        boost::weak_ptr<Process> weakProcessPtr(process);
        TimeoutPtr timerId = elp->runAfter(
                                 request->timeout(),
                                 boost::bind(&Process::onTimeoutWeak, weakProcessPtr)
                             );

        process->setTimerId(timerId);
    }
}

void SlaveServiceImpl::runScript(const ConstRunScriptRequestPtr& request,
                                 const RunCommandResponsePtr& response,
                                 const DoneCallback& done) {

    /*
    RunCommandRequestPtr runCommandReq(new RunCommandRequest);
    std::string scriptFile = writeTempFile(ZurgSlave::instance().getName(), request->script());

    if (!scriptFile.empty()) {
        LOG_INFO << "runScript - write to " << scriptFile;

        // FIXME: interpreter
        runCommandReq->set_command(scriptFile);

        // FIXME: others
        runCommand(runCommandReq, NULL, done);
    }else {
        LOG_ERROR << "runScript - failed to write script file";
        // FIXME: done
    }
    */
}

void SlaveServiceImpl::listProcesses(const ConstListProcessesRequestPtr& request,
                                     const ListProcessesResponsePtr& response,
                                     const DoneCallback& done) {

}

void SlaveServiceImpl::addApplication(const ConstAddApplicationRequestPtr& request,
                                      const AddApplicationResponsePtr& response,
                                      const DoneCallback& done) {
    applicationManager_->add(request, response, done);
}

void SlaveServiceImpl::startApplications(const ConstStartApplicationsRequestPtr& request,
        const StartApplicationsResponsePtr& response,
        const DoneCallback& done) {
    applicationManager_->start(request, response, done);
}

void SlaveServiceImpl::stopApplications(const ConstStopApplicationRequestPtr& request,
                                        const StopApplicationResponsePtr& response,
                                        const DoneCallback& done) {
    applicationManager_->stop(request, response, done);
}

void SlaveServiceImpl::listApplications(const ConstListApplicationsRequestPtr& request,
                                        const ListApplicationsResponsePtr& response,
                                        const DoneCallback& done) {
    applicationManager_->list(request, response, done);
}

void SlaveServiceImpl::removeApplications(const ConstRemoveApplicationsRequestPtr& request,
        const RemoveApplicationsResponsePtr& response,
        const DoneCallback& done) {
    applicationManager_->remove(request, response, done);
}

void SlaveServiceImpl::init() {
    for (size_t i = 0; i < config_.applications.size(); ++i) {
        SlaveServiceConfig::Application* application = config_.applications[i];
        addApplicationFromConfig(application);

        if (application->autoStart) {
            startApplication(application->name);
        }
    }
}

void SlaveServiceImpl::addApplicationFromConfig(SlaveServiceConfig::Application* application) {
    std::string name = application->name;
    boost::scoped_ptr<AddApplicationRequest> request(new AddApplicationRequest);

    request->set_name(name);
    request->set_binary(application->binary);
    request->set_cwd(application->cwd);

    request->set_redirect_stdout(application->redirectStdout);
    request->set_redirect_stderr(application->redirectStderr);
    request->set_auto_recover(application->autoRecover);
    request->set_log_file(application->logFile);

    std::string args;

    for (std::size_t j; j < application->args.size(); ++ j) {
        request->add_args(application->args[j]);
        args += application->args[j];
        args += " ";
    }

    for (std::size_t j = 0; j < application->envs.size(); ++j) {
        request->add_envs(application->envs.at(j));
    }

    boost::scoped_ptr<AddApplicationResponse> response(new AddApplicationResponse);
    addApplication(request.get(),
                   response.get(),
                   DoneCallback());
    LOG_INFO << "add application: " << name
             << " bin: " << application->binary
             << " cwd: " << application->cwd
             << " args: " << args;
}

void SlaveServiceImpl::startApplication(const std::string& name) {
    boost::scoped_ptr<StartApplicationsRequest> request(new StartApplicationsRequest);
    boost::scoped_ptr<StartApplicationsResponse> response(new StartApplicationsResponse);

    request->add_names()->assign(name);
    startApplications(request.get(),
                      response.get(),
                      DoneCallback());

    if (response->status(0).state() == kError) {
        LOG_ERROR << "start application " << name << " failed";
        removeApplication(name);
    }
    else {
        LOG_INFO << "application [" << name << "] "
                 << response->status(0).message();
    }
}

void SlaveServiceImpl::removeApplication(const std::string& name) {
    boost::scoped_ptr<RemoveApplicationsRequest> request(new RemoveApplicationsRequest);
    boost::scoped_ptr<RemoveApplicationsResponse> response(new RemoveApplicationsResponse);
    request->add_name(name);

    removeApplications(request.get(),
                       response.get(),
                       DoneCallback());
}

}
}
}
<commit_msg>fix linux compiler error<commit_after>#include <cetty/zurg/slave/SlaveServiceImpl.h>

#include <boost/weak_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <cetty/util/SmallFile.h>
#include <cetty/config/ConfigCenter.h>
#include <cetty/logging/LoggerHelper.h>
#include <cetty/channel/EventLoopPool.h>

#include <cetty/zurg/Util.h>
#include <cetty/zurg/slave/Process.h>
#include <cetty/zurg/slave/ApplicationManager.h>
#include <cetty/zurg/slave/ProcessManager.h>
#include <cetty/zurg/slave/GetHardwareTask.h>

namespace cetty {
namespace zurg {
namespace slave {

using namespace cetty::zurg;
using namespace cetty::util;
using namespace cetty::channel;
using namespace cetty::config;

SlaveServiceImpl::SlaveServiceImpl(const EventLoopPtr& loop) {
    ConfigCenter::instance().configure(&config_);
    processManager_.reset(new ProcessManager(loop));
    applicationManager_.reset(new ApplicationManager(*processManager_));

    // start all configured applications
    init();
}

SlaveServiceImpl::~SlaveServiceImpl() {

}

void SlaveServiceImpl::getHardware(const ConstGetHardwareRequestPtr& request,
                                   const GetHardwareResponsePtr& response,
                                   const DoneCallback& done) {

    LOG_INFO << "SlaveServiceImpl::getHardware - lshw = "
             << request->lshw();

    GetHardwareTaskPtr task(new GetHardwareTask(request, response, done, *this));
}

void SlaveServiceImpl::getFileContent(const ConstGetFileContentRequestPtr& request,
                                      const GetFileContentResponsePtr& response,
                                      const DoneCallback& done) {

    LOG_INFO << "SlaveServiceImpl::getFileContent - " << request->file_name()
             << " maxSize = " << request->max_size();

    int64_t file_size = 0;
    int64_t modify_time = 0;
    int64_t create_time = 0;
    int err = SmallFile::readFile(request->file_name(),
                                  request->max_size(),
                                  response->mutable_content(),
                                  &file_size,
                                  &modify_time,
                                  &create_time);
    response->set_error_code(err);
    response->set_file_size(file_size);
    response->set_modify_time(modify_time);
    response->set_create_time(create_time);

    LOG_DEBUG << "SlaveServiceImpl::getFileContent - err " << err;
    done(response);
}

void SlaveServiceImpl::getFileChecksum(const ConstGetFileChecksumRequestPtr& request,
                                       const GetFileChecksumResponsePtr& response,
                                       const DoneCallback& done) {

    DLOG_DEBUG ;

    if (request->files_size() > 0) {
        RunCommandRequestPtr runCommandReq(new RunCommandRequest);
        runCommandReq->set_command("md5sum");

        for (int i = 0; i < request->files_size(); ++i) {
            assert(request->files(i).find('\n') == std::string::npos);
            runCommandReq->add_args(request->files(i));
        }

        runCommand(
            runCommandReq,
            NULL,
            boost::bind(&SlaveServiceImpl::getFileChecksumDone,
                        this, request, _1, done)
        );
    }
    else {
        GetFileChecksumResponse response;
        done(&response);
    }
}

void SlaveServiceImpl::getFileChecksumDone(const ConstGetFileChecksumRequestPtr& request,
        const google::protobuf::Message* message,
        const DoneCallback& done) {

    const RunCommandResponse* runCommandResp =
        google::protobuf::down_cast<const RunCommandResponse*>(message);

    const std::string& lines = runCommandResp->std_output();
    std::map<StringPiece, StringPiece> md5sums;
    parseMd5sum(lines, &md5sums);

    GetFileChecksumResponse response;

    for (int i = 0; i < request->files_size(); ++i) {
        md5sums[request->files(i)].copy_to(response.add_md5sums());
    }

    done(&response);
}

void SlaveServiceImpl::runCommand(const ConstRunCommandRequestPtr& request,
                                  const RunCommandResponsePtr& response,
                                  const DoneCallback& done) {

    LOG_INFO << "SlaveServiceImpl::runCommand - " << request->command();

    ProcessPtr process(new Process(request, response, done, true, true,
                                   config_.slaveName,
                                   config_.prefix));

    int err = 12; // ENOMEM;

    try {
        err = process->start();
    }
    catch (...) {}

    if (err) {
        response->set_error_code(err);
        done(response);
    }
    else {
        processManager_->runAtExit(
            process->pid(),  // bind strong ptr
            boost::bind(&Process::onCommandExit,
                        process, _1, _2)
        );

        EventLoopPtr elp = EventLoopPool::current();
        assert(elp);
        boost::weak_ptr<Process> weakProcessPtr(process);
        TimeoutPtr timerId = elp->runAfter(
                                 request->timeout(),
                                 boost::bind(&Process::onTimeoutWeak, weakProcessPtr)
                             );

        process->setTimerId(timerId);
    }
}

void SlaveServiceImpl::runScript(const ConstRunScriptRequestPtr& request,
                                 const RunCommandResponsePtr& response,
                                 const DoneCallback& done) {

    /*
    RunCommandRequestPtr runCommandReq(new RunCommandRequest);
    std::string scriptFile = writeTempFile(ZurgSlave::instance().getName(), request->script());

    if (!scriptFile.empty()) {
        LOG_INFO << "runScript - write to " << scriptFile;

        // FIXME: interpreter
        runCommandReq->set_command(scriptFile);

        // FIXME: others
        runCommand(runCommandReq, NULL, done);
    }else {
        LOG_ERROR << "runScript - failed to write script file";
        // FIXME: done
    }
    */
}

void SlaveServiceImpl::listProcesses(const ConstListProcessesRequestPtr& request,
                                     const ListProcessesResponsePtr& response,
                                     const DoneCallback& done) {

}

void SlaveServiceImpl::addApplication(const ConstAddApplicationRequestPtr& request,
                                      const AddApplicationResponsePtr& response,
                                      const DoneCallback& done) {
    applicationManager_->add(request, response, done);
}

void SlaveServiceImpl::startApplications(const ConstStartApplicationsRequestPtr& request,
        const StartApplicationsResponsePtr& response,
        const DoneCallback& done) {
    applicationManager_->start(request, response, done);
}

void SlaveServiceImpl::stopApplications(const ConstStopApplicationRequestPtr& request,
                                        const StopApplicationResponsePtr& response,
                                        const DoneCallback& done) {
    applicationManager_->stop(request, response, done);
}

void SlaveServiceImpl::listApplications(const ConstListApplicationsRequestPtr& request,
                                        const ListApplicationsResponsePtr& response,
                                        const DoneCallback& done) {
    applicationManager_->list(request, response, done);
}

void SlaveServiceImpl::removeApplications(const ConstRemoveApplicationsRequestPtr& request,
        const RemoveApplicationsResponsePtr& response,
        const DoneCallback& done) {
    applicationManager_->remove(request, response, done);
}

void SlaveServiceImpl::init() {
    for (size_t i = 0; i < config_.applications.size(); ++i) {
        SlaveServiceConfig::Application* application = config_.applications[i];
        addApplicationFromConfig(application);

        if (application->autoStart) {
            startApplication(application->name);
        }
    }
}

void SlaveServiceImpl::addApplicationFromConfig(SlaveServiceConfig::Application* application) {
    std::string name = application->name;
    boost::scoped_ptr<AddApplicationRequest> request(new AddApplicationRequest);

    request->set_name(name);
    request->set_binary(application->binary);
    request->set_cwd(application->cwd);

    request->set_redirect_stdout(application->redirectStdout);
    request->set_redirect_stderr(application->redirectStderr);
    request->set_auto_recover(application->autoRecover);
    request->set_log_file(application->logFile);

    std::string args;

    for (std::size_t j; j < application->args.size(); ++ j) {
        request->add_args(application->args[j]);
        args += application->args[j];
        args += " ";
    }

    for (std::size_t j = 0; j < application->envs.size(); ++j) {
        request->add_envs(application->envs.at(j));
    }

    boost::scoped_ptr<AddApplicationResponse> response(new AddApplicationResponse);
    addApplication(request.get(),
                   response.get(),
                   DoneCallback());
    LOG_INFO << "add application: " << name
             << " bin: " << application->binary
             << " cwd: " << application->cwd
             << " args: " << args;
}

void SlaveServiceImpl::startApplication(const std::string& name) {
    boost::scoped_ptr<StartApplicationsRequest> request(new StartApplicationsRequest);
    boost::scoped_ptr<StartApplicationsResponse> response(new StartApplicationsResponse);

    request->add_names()->assign(name);
    startApplications(request.get(),
                      response.get(),
                      DoneCallback());

    if (response->status(0).state() == kError) {
        LOG_ERROR << "start application " << name << " failed";
        removeApplication(name);
    }
    else {
        LOG_INFO << "application [" << name << "] "
                 << response->status(0).message();
    }
}

void SlaveServiceImpl::removeApplication(const std::string& name) {
    boost::scoped_ptr<RemoveApplicationsRequest> request(new RemoveApplicationsRequest);
    boost::scoped_ptr<RemoveApplicationsResponse> response(new RemoveApplicationsResponse);
    request->add_name(name);

    removeApplications(request.get(),
                       response.get(),
                       DoneCallback());
}

}
}
}
<|endoftext|>


<commit_before>#include "Eci.h"

Eci::Eci(const Julian &date, const CoordGeodetic &geo)
: date_(date) {

    static const double mfactor = Globals::TWOPI() * (Globals::OMEGA_E() / Globals::SEC_PER_DAY());
    const double latitude = geo.GetLatitude();
    const double longitude = geo.GetLongitude();
    const double altitude = geo.GetAltitude();

    /*
     * Calculate Local Mean Sidereal Time for observers longitude
     */
    const double theta = date_.ToLocalMeanSiderealTime(longitude);

    /*
     * take into account earth flattening
     */
    const double c = 1.0 / sqrt(1.0 + Globals::F() * (Globals::F() - 2.0) * pow(sin(latitude), 2.0));
    const double s = pow(1.0 - Globals::F(), 2.0) * c;
    const double achcp = (Globals::XKMPER() * c + altitude) * cos(latitude);

    /*
     * X position in km
     * Y position in km
     * Z position in km
     * W magnitude in km
     */
    position_.SetX(achcp * cos(theta));
    position_.SetY(achcp * sin(theta));
    position_.SetZ((Globals::XKMPER() * s + altitude) * sin(latitude));
    position_.SetW(position_.GetMagnitude());

    /*
     * X velocity in km/s
     * Y velocity in km/s
     * Z velocity in km/s
     * W magnitude in km/s
     */
    velocity_.SetX(-mfactor * position_.GetY());
    velocity_.SetY(mfactor * position_.GetX());
    velocity_.SetZ(0.0);
    velocity_.SetW(velocity_.GetMagnitude());
}

Eci::Eci(const Julian &date, const Vector &position, const Vector &velocity)
: date_(date), position_(position), velocity_(velocity) {

}

Eci::~Eci(void) {
}

CoordGeodetic Eci::ToGeodetic() const {

    const double theta = Globals::AcTan(position_.GetY(), position_.GetX());
    const double lon = Globals::Fmod2p(theta - date_.ToGreenwichSiderealTime());
    const double r = sqrt((position_.GetX() * position_.GetX()) + (position_.GetY() * position_.GetY()));
    const double e2 = Globals::F() * (2.0 - Globals::F());

    double lat = Globals::AcTan(position_.GetZ(), r);
    double phi = 0.0;
    double c = 0.0;

    do {
        phi = lat;
        const double sinphi = sin(phi);
        c = 1 / sqrt(1 - e2 * sinphi * sinphi);
        lat = Globals::AcTan(position_.GetZ() + Globals::XKMPER() * c * e2 * sinphi, r);
    } while (fabs(lat - phi) >= 1e-10);

    const double alt = r / cos(lat) - Globals::XKMPER() * c;

    /*
     * todo: check
     */
    //if (lat > pio2) geodetic->lat -= twopi;

    return CoordGeodetic(lat, lon, alt);
}
<commit_msg>Changed longitude to -180 to 180<commit_after>#include "Eci.h"

Eci::Eci(const Julian &date, const CoordGeodetic &geo)
: date_(date) {

    static const double mfactor = Globals::TWOPI() * (Globals::OMEGA_E() / Globals::SEC_PER_DAY());
    const double latitude = geo.GetLatitude();
    const double longitude = geo.GetLongitude();
    const double altitude = geo.GetAltitude();

    /*
     * Calculate Local Mean Sidereal Time for observers longitude
     */
    const double theta = date_.ToLocalMeanSiderealTime(longitude);

    /*
     * take into account earth flattening
     */
    const double c = 1.0 / sqrt(1.0 + Globals::F() * (Globals::F() - 2.0) * pow(sin(latitude), 2.0));
    const double s = pow(1.0 - Globals::F(), 2.0) * c;
    const double achcp = (Globals::XKMPER() * c + altitude) * cos(latitude);

    /*
     * X position in km
     * Y position in km
     * Z position in km
     * W magnitude in km
     */
    position_.SetX(achcp * cos(theta));
    position_.SetY(achcp * sin(theta));
    position_.SetZ((Globals::XKMPER() * s + altitude) * sin(latitude));
    position_.SetW(position_.GetMagnitude());

    /*
     * X velocity in km/s
     * Y velocity in km/s
     * Z velocity in km/s
     * W magnitude in km/s
     */
    velocity_.SetX(-mfactor * position_.GetY());
    velocity_.SetY(mfactor * position_.GetX());
    velocity_.SetZ(0.0);
    velocity_.SetW(velocity_.GetMagnitude());
}

Eci::Eci(const Julian &date, const Vector &position, const Vector &velocity)
: date_(date), position_(position), velocity_(velocity) {

}

Eci::~Eci(void) {
}

CoordGeodetic Eci::ToGeodetic() const {

    const double theta = Globals::AcTan(position_.GetY(), position_.GetX());
    /*
     * changes lon to 0>= and <360
     * const double lon = Globals::Fmod2p(theta - date_.ToGreenwichSiderealTime());
     */
    const double lon = fmod(theta - date_.ToGreenwichSiderealTime(), Globals::TWOPI());
    const double r = sqrt((position_.GetX() * position_.GetX()) + (position_.GetY() * position_.GetY()));
    static const double e2 = Globals::F() * (2.0 - Globals::F());

    double lat = Globals::AcTan(position_.GetZ(), r);
    double phi = 0.0;
    double c = 0.0;

    do {
        phi = lat;
        const double sinphi = sin(phi);
        c = 1.0 / sqrt(1.0 - e2 * sinphi * sinphi);
        lat = Globals::AcTan(position_.GetZ() + Globals::XKMPER() * c * e2 * sinphi, r);
    } while (fabs(lat - phi) >= 1e-10);

    const double alt = r / cos(lat) - Globals::XKMPER() * c;

    return CoordGeodetic(lat, lon, alt);
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 ASMlover. 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 ofconditions 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 materialsprovided 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.
#include "eutil.h"
#include "el_ini_parser.h"

namespace el {

struct Token {
  enum class Type {
    TYPE_ERR = 0,
    TYPE_EOF,
    TYPE_COMMENT,

    TYPE_VALUE,

    TYPE_LBRACKET,
    TYPE_RBRACKET,
    TYPE_ASSIGN,
  };

  Type        type;
  std::string value;
};

class IniLexer : private UnCopyable {
  enum {BSIZE = 256};
  enum class State {
    STATE_BEGIN = 0,
    STATE_FINISH,

    STATE_VALUE,
    STATE_COMMENT,
  };

  typedef std::shared_ptr<FILE> FilePtr;

  int     lineno_;
  int     bsize_;
  bool    eof_;
  FilePtr file_;
  int     lexpos_;
  char    lexbuf_[BSIZE];
public:
  IniLexer(void);
  ~IniLexer(void);

  bool Open(const char* fname);
  void Close(void);

  Token::Type GetToken(Token& token);
private:
  int GetChar(void);
  void UngetChar(void);

  Token::Type LexerBegin(int c, State& out_state, bool& out_save);
  Token::Type LexerFinish(int c, State& out_state, bool& out_save);
  Token::Type LexerValue(int c, State& out_state, bool& out_save);
  Token::Type LexerComment(int c, State& out_state, bool& out_save);
};

IniLexer::IniLexer(void)
  : lineno_(1)
  , bsize_(0)
  , eof_(false)
  , file_(FilePtr(nullptr))
  , lexpos_(0) {
}

IniLexer::~IniLexer(void) {
}

bool IniLexer::Open(const char* fname) {
  file_.reset(fopen(fname, "r"), fclose);
  if (!file_)
    return false;

  lineno_ = 1;
  bsize_  = 0;
  eof_    = false;
  lexpos_ = 0;

  return true;
}

void IniLexer::Close(void) {
}

Token::Type IniLexer::GetToken(Token& token) {
  Token::Type type = Token::Type::TYPE_ERR;
  State state = State::STATE_BEGIN;
  bool  save;
  int   c;

  token.value.clear();
  while (State::STATE_FINISH != state) {
    c = GetChar();
    save = true;

    switch (state) {
    case State::STATE_BEGIN:
      type = LexerBegin(c, state, save);
      break;
    case State::STATE_FINISH:
      type = LexerFinish(c, state, save);
      break;
    case State::STATE_VALUE:
      type = LexerValue(c, state, save);
      break;
    case State::STATE_COMMENT:
      type = LexerComment(c, state, save);
      break;
    }

    if (save)
      token.value += static_cast<char>(c);
    if (State::STATE_FINISH == state)
      token.type = type;
  }

  return type;
}

int IniLexer::GetChar(void) {
  if (lexpos_ >= bsize_) {
    if (nullptr != fgets(lexbuf_, BSIZE, file_.get())) {
      bsize_ = static_cast<int>(strlen(lexbuf_));
      lexpos_ = 0;
    }
    else {
      eof_ = true;
      return EOF;
    }
  }

  return lexbuf_[lexpos_++];
}

void IniLexer::UngetChar(void) {
  if (!eof_)
    --lexpos_;
}

Token::Type IniLexer::LexerBegin(
    int c, State& out_state, bool& out_save) {
  Token::Type type = Token::Type::TYPE_ERR;

  if (' ' == c || '\t' == c) {
    out_save = false;
  }
  else if ('\n' == c) {
    out_save = false;
    ++lineno_;
  }
  else if ('#' == c) {
    out_state = State::STATE_COMMENT;
    out_save = false;
  }
  else if ('[' == c) {
    out_state = State::STATE_FINISH;
    type = Token::Type::TYPE_LBRACKET;
  }
  else if (']' == c) {
    out_state = State::STATE_FINISH;
    type = Token::Type::TYPE_RBRACKET;
  }
  else if ('=' == c) {
    out_state = State::STATE_FINISH;
    type = Token::Type::TYPE_ASSIGN;
  }
  else if (EOF == c) {
    out_state = State::STATE_FINISH;
    out_save = false;
    type = Token::Type::TYPE_EOF;
  }
  else {
    out_state = State::STATE_VALUE;
  }

  return type;
}

Token::Type IniLexer::LexerFinish(
    int c, State& out_state, bool& out_save) {
  out_state = State::STATE_FINISH;
  out_save = false;

  return Token::Type::TYPE_ERR;;
}

Token::Type IniLexer::LexerValue(
    int c, State& out_state, bool& out_save) {
  if (' ' == c || '\t' == c || '\n' == c
      || '#' == c || '=' == c || ']' == c) {
    if ('\n' == c || '#' == c || '=' == c || ']' == c)
      UngetChar();

    out_state = State::STATE_FINISH;
    out_save = false;

    return Token::Type::TYPE_VALUE;
  }

  return Token::Type::TYPE_ERR;
}

Token::Type IniLexer::LexerComment(
    int c, State& out_state, bool& out_save) {
  out_save = false;
  if (EOF == c) {
    out_state = State::STATE_FINISH;
    return Token::Type::TYPE_EOF;
  }
  else if ('\n' == c) {
    ++lineno_;
    out_state = State::STATE_BEGIN;
  }

  return Token::Type::TYPE_ERR;
}

IniParser::IniParser(void)
  : lexer_(IniLexerPtr(new IniLexer()))
  , section_("") {
}

IniParser::~IniParser(void) {
}

bool IniParser::Open(const char* fname) {
  return true;
}

void IniParser::Close(void) {
}

std::string IniParser::Get(
    const std::string& section, const std::string& key) {
  return "";
}

void IniParser::Parse(void) {
}

void IniParser::ParseSection(void) {
}

void IniParser::ParseValue(const std::string& value) {
}

}
<commit_msg>improved the implementation of ini lexer<commit_after>// Copyright (c) 2014 ASMlover. 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 ofconditions 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 materialsprovided 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.
#include "eutil.h"
#include "el_ini_parser.h"

namespace el {

enum class Type {
  TYPE_ERR = 0,
  TYPE_EOF,
  TYPE_COMMENT,

  TYPE_VALUE,

  TYPE_LBRACKET,
  TYPE_RBRACKET,
  TYPE_ASSIGN,
};

class IniLexer : private UnCopyable {
  enum {BSIZE = 256};
  enum class State {
    STATE_BEGIN = 0,
    STATE_FINISH,

    STATE_VALUE,
    STATE_COMMENT,
  };

  typedef std::shared_ptr<FILE> FilePtr;

  int     lineno_;
  int     bsize_;
  bool    eof_;
  FilePtr file_;
  int     lexpos_;
  char    lexbuf_[BSIZE];
public:
  IniLexer(void);
  ~IniLexer(void);

  bool Open(const char* fname);
  void Close(void);

  Type GetToken(std::string& token);
private:
  int GetChar(void);
  void UngetChar(void);

  Type LexerBegin(int c, State& out_state, bool& out_save);
  Type LexerFinish(int c, State& out_state, bool& out_save);
  Type LexerValue(int c, State& out_state, bool& out_save);
  Type LexerComment(int c, State& out_state, bool& out_save);
};

IniLexer::IniLexer(void)
  : lineno_(1)
  , bsize_(0)
  , eof_(false)
  , file_(FilePtr(nullptr))
  , lexpos_(0) {
}

IniLexer::~IniLexer(void) {
}

bool IniLexer::Open(const char* fname) {
  file_.reset(fopen(fname, "r"), fclose);
  if (!file_)
    return false;

  lineno_ = 1;
  bsize_  = 0;
  eof_    = false;
  lexpos_ = 0;

  return true;
}

void IniLexer::Close(void) {
}

Type IniLexer::GetToken(std::string& token) {
  Type type = Type::TYPE_ERR;
  State state = State::STATE_BEGIN;
  bool  save;
  int   c;

  token.clear();
  while (State::STATE_FINISH != state) {
    c = GetChar();
    save = true;

    switch (state) {
    case State::STATE_BEGIN:
      type = LexerBegin(c, state, save);
      break;
    case State::STATE_FINISH:
      type = LexerFinish(c, state, save);
      break;
    case State::STATE_VALUE:
      type = LexerValue(c, state, save);
      break;
    case State::STATE_COMMENT:
      type = LexerComment(c, state, save);
      break;
    }

    if (save)
      token += static_cast<char>(c);
  }

  return type;
}

int IniLexer::GetChar(void) {
  if (lexpos_ >= bsize_) {
    if (nullptr != fgets(lexbuf_, BSIZE, file_.get())) {
      bsize_ = static_cast<int>(strlen(lexbuf_));
      lexpos_ = 0;
    }
    else {
      eof_ = true;
      return EOF;
    }
  }

  return lexbuf_[lexpos_++];
}

void IniLexer::UngetChar(void) {
  if (!eof_)
    --lexpos_;
}

Type IniLexer::LexerBegin(
    int c, State& out_state, bool& out_save) {
  Type type = Type::TYPE_ERR;

  if (' ' == c || '\t' == c) {
    out_save = false;
  }
  else if ('\n' == c) {
    out_save = false;
    ++lineno_;
  }
  else if ('#' == c) {
    out_state = State::STATE_COMMENT;
    out_save = false;
  }
  else if ('[' == c) {
    out_state = State::STATE_FINISH;
    type = Type::TYPE_LBRACKET;
  }
  else if (']' == c) {
    out_state = State::STATE_FINISH;
    type = Type::TYPE_RBRACKET;
  }
  else if ('=' == c) {
    out_state = State::STATE_FINISH;
    type = Type::TYPE_ASSIGN;
  }
  else if (EOF == c) {
    out_state = State::STATE_FINISH;
    out_save = false;
    type = Type::TYPE_EOF;
  }
  else {
    out_state = State::STATE_VALUE;
  }

  return type;
}

Type IniLexer::LexerFinish(
    int c, State& out_state, bool& out_save) {
  out_state = State::STATE_FINISH;
  out_save = false;

  return Type::TYPE_ERR;;
}

Type IniLexer::LexerValue(
    int c, State& out_state, bool& out_save) {
  if (' ' == c || '\t' == c || '\n' == c
      || '#' == c || '=' == c || ']' == c) {
    if ('\n' == c || '#' == c || '=' == c || ']' == c)
      UngetChar();

    out_state = State::STATE_FINISH;
    out_save = false;

    return Type::TYPE_VALUE;
  }

  return Type::TYPE_ERR;
}

Type IniLexer::LexerComment(
    int c, State& out_state, bool& out_save) {
  out_save = false;
  if (EOF == c) {
    out_state = State::STATE_FINISH;
    return Type::TYPE_EOF;
  }
  else if ('\n' == c) {
    ++lineno_;
    out_state = State::STATE_BEGIN;
  }

  return Type::TYPE_ERR;
}

IniParser::IniParser(void)
  : lexer_(IniLexerPtr(new IniLexer()))
  , section_("") {
}

IniParser::~IniParser(void) {
}

bool IniParser::Open(const char* fname) {
  return true;
}

void IniParser::Close(void) {
}

std::string IniParser::Get(
    const std::string& section, const std::string& key) {
  return "";
}

void IniParser::Parse(void) {
}

void IniParser::ParseSection(void) {
}

void IniParser::ParseValue(const std::string& value) {
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 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 "chrome/browser/renderer_host/render_widget_helper.h"

#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"

// A Task used with InvokeLater that we hold a pointer to in pending_paints_.
// Instances are deleted by MessageLoop after it calls their Run method.
class RenderWidgetHelper::PaintMsgProxy : public Task {
 public:
  PaintMsgProxy(RenderWidgetHelper* h, const IPC::Message& m)
      : helper(h),
        message(m),
        cancelled(false) {
  }

  ~PaintMsgProxy() {
    // If the paint message was never dispatched, then we need to let the
    // helper know that we are going away.
    if (!cancelled && helper)
      helper->OnDiscardPaintMsg(this);
  }

  virtual void Run() {
    if (!cancelled) {
      helper->OnDispatchPaintMsg(this);
      helper = NULL;
    }
  }

  scoped_refptr<RenderWidgetHelper> helper;
  IPC::Message message;
  bool cancelled;  // If true, then the message will not be dispatched.

  DISALLOW_COPY_AND_ASSIGN(PaintMsgProxy);
};

RenderWidgetHelper::RenderWidgetHelper(int render_process_id)
    : render_process_id_(render_process_id),
      ui_loop_(MessageLoop::current()),
      event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)),
      block_popups_(false) {
}

RenderWidgetHelper::~RenderWidgetHelper() {
  // The elements of pending_paints_ each hold an owning reference back to this
  // object, so we should not be destroyed unless pending_paints_ is empty!
  DCHECK(pending_paints_.empty());
}

int RenderWidgetHelper::GetNextRoutingID() {
  return next_routing_id_.GetNext() + 1;
}

void RenderWidgetHelper::CancelResourceRequests(int render_widget_id) {
  if (g_browser_process->io_thread()) {
    g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
        NewRunnableMethod(this,
                          &RenderWidgetHelper::OnCancelResourceRequests,
                          g_browser_process->resource_dispatcher_host(),
                          render_widget_id));
  }
}

void RenderWidgetHelper::CrossSiteClosePageACK(int new_render_process_host_id,
                                               int new_request_id) {
  if (g_browser_process->io_thread()) {
    g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
        NewRunnableMethod(this,
                          &RenderWidgetHelper::OnCrossSiteClosePageACK,
                          g_browser_process->resource_dispatcher_host(),
                          new_render_process_host_id,
                          new_request_id));
  }
}

bool RenderWidgetHelper::WaitForPaintMsg(int render_widget_id,
                                         const base::TimeDelta& max_delay,
                                         IPC::Message* msg) {
  base::TimeTicks time_start = base::TimeTicks::Now();

  for (;;) {
    PaintMsgProxy* proxy = NULL;
    {
      AutoLock lock(pending_paints_lock_);

      PaintMsgProxyMap::iterator it = pending_paints_.find(render_widget_id);
      if (it != pending_paints_.end()) {
        proxy = it->second;

        // Flag the proxy as cancelled so that when it is run as a task it will
        // do nothing.
        proxy->cancelled = true;

        pending_paints_.erase(it);
      }
    }

    if (proxy) {
      *msg = proxy->message;
      DCHECK(msg->routing_id() == render_widget_id);
      return true;
    }

    // Calculate the maximum amount of time that we are willing to sleep.
    base::TimeDelta max_sleep_time =
        max_delay - (base::TimeTicks::Now() - time_start);
    if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0))
      break;

    event_.TimedWait(max_sleep_time);
  }

  return false;
}

void RenderWidgetHelper::DidReceivePaintMsg(const IPC::Message& msg) {
  int render_widget_id = msg.routing_id();

  PaintMsgProxy* proxy;
  {
    AutoLock lock(pending_paints_lock_);

    PaintMsgProxyMap::value_type new_value(render_widget_id, NULL);

    // We expect only a single PaintRect message at a time.  Optimize for the
    // case that we don't already have an entry by using the 'insert' method.
    std::pair<PaintMsgProxyMap::iterator, bool> result =
        pending_paints_.insert(new_value);
    if (!result.second) {
      NOTREACHED() << "Unexpected PaintRect message!";
      return;
    }

    result.first->second = (proxy = new PaintMsgProxy(this, msg));
  }

  // Notify anyone waiting on the UI thread that there is a new entry in the
  // proxy map.  If they don't find the entry they are looking for, then they
  // will just continue waiting.
  event_.Signal();

  // The proxy will be deleted when it is run as a task.
  ui_loop_->PostTask(FROM_HERE, proxy);
}

void RenderWidgetHelper::OnDiscardPaintMsg(PaintMsgProxy* proxy) {
  const IPC::Message& msg = proxy->message;

  // Remove the proxy from the map now that we are going to handle it normally.
  {
    AutoLock lock(pending_paints_lock_);

    PaintMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id());
    DCHECK(it != pending_paints_.end());
    DCHECK(it->second == proxy);

    pending_paints_.erase(it);
  }
}

void RenderWidgetHelper::OnDispatchPaintMsg(PaintMsgProxy* proxy) {
  OnDiscardPaintMsg(proxy);

  // It is reasonable for the host to no longer exist.
  RenderProcessHost* host = RenderProcessHost::FromID(render_process_id_);
  if (host)
    host->OnMessageReceived(proxy->message);
}

void RenderWidgetHelper::OnCancelResourceRequests(
    ResourceDispatcherHost* dispatcher,
    int render_widget_id) {
  dispatcher->CancelRequestsForRenderView(render_process_id_, render_widget_id);
}

void RenderWidgetHelper::OnCrossSiteClosePageACK(
    ResourceDispatcherHost* dispatcher,
    int new_render_process_host_id,
    int new_request_id) {
  dispatcher->OnClosePageACK(new_render_process_host_id, new_request_id);
}

void RenderWidgetHelper::CreateNewWindow(int opener_id,
                                         bool user_gesture,
                                         base::ProcessHandle render_process,
                                         int* route_id
#if defined(OS_WIN)
                                         , HANDLE* modal_dialog_event) {
#else
                                         ) {
#endif
  if (!user_gesture && block_popups_) {
    *route_id = MSG_ROUTING_NONE;
    *modal_dialog_event = NULL;
    return;
  }

  *route_id = GetNextRoutingID();

#if defined(OS_WIN)
  ModalDialogEvent event;
  event.event = CreateEvent(NULL, TRUE, FALSE, NULL);
  BOOL result = DuplicateHandle(GetCurrentProcess(),
                                event,
                                render_process,
                                modal_dialog_event,
                                SYNCHRONIZE,
                                FALSE,
                                0);
  DCHECK(result) << "Couldn't duplicate modal dialog event for the renderer.";

  // The easiest way to reach RenderViewHost is just to send a routed message.
  ViewHostMsg_CreateWindowWithRoute msg(opener_id, *route_id, event);
#else
  // TODO(port) figure out how the modal dialog event should work.
  ViewHostMsg_CreateWindowWithRoute msg(opener_id, *route_id);
#endif

  ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
      this, &RenderWidgetHelper::OnSimulateReceivedMessage, msg));
}

void RenderWidgetHelper::CreateNewWidget(int opener_id,
                                         bool activatable,
                                         int* route_id) {
  *route_id = GetNextRoutingID();
  ViewHostMsg_CreateWidgetWithRoute msg(opener_id, *route_id, activatable);
  ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
      this, &RenderWidgetHelper::OnSimulateReceivedMessage, msg));
}

void RenderWidgetHelper::OnSimulateReceivedMessage(
    const IPC::Message& message) {
  RenderProcessHost* host = RenderProcessHost::FromID(render_process_id_);
  if (host)
    host->OnMessageReceived(message);
}
<commit_msg>Fix the build. Review URL: http://codereview.chromium.org/18790<commit_after>// Copyright (c) 2006-2008 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 "chrome/browser/renderer_host/render_widget_helper.h"

#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"

// A Task used with InvokeLater that we hold a pointer to in pending_paints_.
// Instances are deleted by MessageLoop after it calls their Run method.
class RenderWidgetHelper::PaintMsgProxy : public Task {
 public:
  PaintMsgProxy(RenderWidgetHelper* h, const IPC::Message& m)
      : helper(h),
        message(m),
        cancelled(false) {
  }

  ~PaintMsgProxy() {
    // If the paint message was never dispatched, then we need to let the
    // helper know that we are going away.
    if (!cancelled && helper)
      helper->OnDiscardPaintMsg(this);
  }

  virtual void Run() {
    if (!cancelled) {
      helper->OnDispatchPaintMsg(this);
      helper = NULL;
    }
  }

  scoped_refptr<RenderWidgetHelper> helper;
  IPC::Message message;
  bool cancelled;  // If true, then the message will not be dispatched.

  DISALLOW_COPY_AND_ASSIGN(PaintMsgProxy);
};

RenderWidgetHelper::RenderWidgetHelper(int render_process_id)
    : render_process_id_(render_process_id),
      ui_loop_(MessageLoop::current()),
      event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)),
      block_popups_(false) {
}

RenderWidgetHelper::~RenderWidgetHelper() {
  // The elements of pending_paints_ each hold an owning reference back to this
  // object, so we should not be destroyed unless pending_paints_ is empty!
  DCHECK(pending_paints_.empty());
}

int RenderWidgetHelper::GetNextRoutingID() {
  return next_routing_id_.GetNext() + 1;
}

void RenderWidgetHelper::CancelResourceRequests(int render_widget_id) {
  if (g_browser_process->io_thread()) {
    g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
        NewRunnableMethod(this,
                          &RenderWidgetHelper::OnCancelResourceRequests,
                          g_browser_process->resource_dispatcher_host(),
                          render_widget_id));
  }
}

void RenderWidgetHelper::CrossSiteClosePageACK(int new_render_process_host_id,
                                               int new_request_id) {
  if (g_browser_process->io_thread()) {
    g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
        NewRunnableMethod(this,
                          &RenderWidgetHelper::OnCrossSiteClosePageACK,
                          g_browser_process->resource_dispatcher_host(),
                          new_render_process_host_id,
                          new_request_id));
  }
}

bool RenderWidgetHelper::WaitForPaintMsg(int render_widget_id,
                                         const base::TimeDelta& max_delay,
                                         IPC::Message* msg) {
  base::TimeTicks time_start = base::TimeTicks::Now();

  for (;;) {
    PaintMsgProxy* proxy = NULL;
    {
      AutoLock lock(pending_paints_lock_);

      PaintMsgProxyMap::iterator it = pending_paints_.find(render_widget_id);
      if (it != pending_paints_.end()) {
        proxy = it->second;

        // Flag the proxy as cancelled so that when it is run as a task it will
        // do nothing.
        proxy->cancelled = true;

        pending_paints_.erase(it);
      }
    }

    if (proxy) {
      *msg = proxy->message;
      DCHECK(msg->routing_id() == render_widget_id);
      return true;
    }

    // Calculate the maximum amount of time that we are willing to sleep.
    base::TimeDelta max_sleep_time =
        max_delay - (base::TimeTicks::Now() - time_start);
    if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0))
      break;

    event_.TimedWait(max_sleep_time);
  }

  return false;
}

void RenderWidgetHelper::DidReceivePaintMsg(const IPC::Message& msg) {
  int render_widget_id = msg.routing_id();

  PaintMsgProxy* proxy;
  {
    AutoLock lock(pending_paints_lock_);

    PaintMsgProxyMap::value_type new_value(render_widget_id, NULL);

    // We expect only a single PaintRect message at a time.  Optimize for the
    // case that we don't already have an entry by using the 'insert' method.
    std::pair<PaintMsgProxyMap::iterator, bool> result =
        pending_paints_.insert(new_value);
    if (!result.second) {
      NOTREACHED() << "Unexpected PaintRect message!";
      return;
    }

    result.first->second = (proxy = new PaintMsgProxy(this, msg));
  }

  // Notify anyone waiting on the UI thread that there is a new entry in the
  // proxy map.  If they don't find the entry they are looking for, then they
  // will just continue waiting.
  event_.Signal();

  // The proxy will be deleted when it is run as a task.
  ui_loop_->PostTask(FROM_HERE, proxy);
}

void RenderWidgetHelper::OnDiscardPaintMsg(PaintMsgProxy* proxy) {
  const IPC::Message& msg = proxy->message;

  // Remove the proxy from the map now that we are going to handle it normally.
  {
    AutoLock lock(pending_paints_lock_);

    PaintMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id());
    DCHECK(it != pending_paints_.end());
    DCHECK(it->second == proxy);

    pending_paints_.erase(it);
  }
}

void RenderWidgetHelper::OnDispatchPaintMsg(PaintMsgProxy* proxy) {
  OnDiscardPaintMsg(proxy);

  // It is reasonable for the host to no longer exist.
  RenderProcessHost* host = RenderProcessHost::FromID(render_process_id_);
  if (host)
    host->OnMessageReceived(proxy->message);
}

void RenderWidgetHelper::OnCancelResourceRequests(
    ResourceDispatcherHost* dispatcher,
    int render_widget_id) {
  dispatcher->CancelRequestsForRenderView(render_process_id_, render_widget_id);
}

void RenderWidgetHelper::OnCrossSiteClosePageACK(
    ResourceDispatcherHost* dispatcher,
    int new_render_process_host_id,
    int new_request_id) {
  dispatcher->OnClosePageACK(new_render_process_host_id, new_request_id);
}

void RenderWidgetHelper::CreateNewWindow(int opener_id,
                                         bool user_gesture,
                                         base::ProcessHandle render_process,
                                         int* route_id
#if defined(OS_WIN)
                                         , HANDLE* modal_dialog_event) {
#else
                                         ) {
#endif
  if (!user_gesture && block_popups_) {
    *route_id = MSG_ROUTING_NONE;
    *modal_dialog_event = NULL;
    return;
  }

  *route_id = GetNextRoutingID();

#if defined(OS_WIN)
  ModalDialogEvent event;
  event.event = CreateEvent(NULL, TRUE, FALSE, NULL);
  BOOL result = DuplicateHandle(GetCurrentProcess(),
                                event.event,
                                render_process,
                                modal_dialog_event,
                                SYNCHRONIZE,
                                FALSE,
                                0);
  DCHECK(result) << "Couldn't duplicate modal dialog event for the renderer.";

  // The easiest way to reach RenderViewHost is just to send a routed message.
  ViewHostMsg_CreateWindowWithRoute msg(opener_id, *route_id, event);
#else
  // TODO(port) figure out how the modal dialog event should work.
  ViewHostMsg_CreateWindowWithRoute msg(opener_id, *route_id);
#endif

  ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
      this, &RenderWidgetHelper::OnSimulateReceivedMessage, msg));
}

void RenderWidgetHelper::CreateNewWidget(int opener_id,
                                         bool activatable,
                                         int* route_id) {
  *route_id = GetNextRoutingID();
  ViewHostMsg_CreateWidgetWithRoute msg(opener_id, *route_id, activatable);
  ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
      this, &RenderWidgetHelper::OnSimulateReceivedMessage, msg));
}

void RenderWidgetHelper::OnSimulateReceivedMessage(
    const IPC::Message& message) {
  RenderProcessHost* host = RenderProcessHost::FromID(render_process_id_);
  if (host)
    host->OnMessageReceived(message);
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "chrome/browser/ui/gtk/bookmark_sub_menu_model_gtk.h"

#include "base/stl_util.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/event_disposition.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h"
#include "chrome/browser/ui/gtk/menu_gtk.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

BookmarkNodeMenuModel::BookmarkNodeMenuModel(
    ui::SimpleMenuModel::Delegate* delegate,
    BookmarkModel* model,
    const BookmarkNode* node,
    PageNavigator* page_navigator)
    : SimpleMenuModel(delegate),
      model_(model),
      node_(node),
      page_navigator_(page_navigator) {
  DCHECK(page_navigator_);
}

BookmarkNodeMenuModel::~BookmarkNodeMenuModel() {
  Clear();
}

void BookmarkNodeMenuModel::Clear() {
  SimpleMenuModel::Clear();
  STLDeleteElements(&submenus_);
}

void BookmarkNodeMenuModel::MenuWillShow() {
  Clear();
  PopulateMenu();
}

void BookmarkNodeMenuModel::MenuClosed() {
  Clear();
}

void BookmarkNodeMenuModel::ActivatedAt(int index) {
  NavigateToMenuItem(index, CURRENT_TAB);
}

void BookmarkNodeMenuModel::ActivatedAt(int index, int event_flags) {
  NavigateToMenuItem(index, browser::DispositionFromEventFlags(event_flags));
}

void BookmarkNodeMenuModel::PopulateMenu() {
  DCHECK(submenus_.empty());
  for (int i = 0; i < node_->child_count(); ++i) {
    const BookmarkNode* child = node_->GetChild(i);
    if (child->is_folder()) {
      AddSubMenuForNode(child);
    } else {
      // Ironically the label will end up getting converted back to UTF8 later.
      const string16 label =
        UTF8ToUTF16(bookmark_utils::BuildMenuLabelFor(child));
      // No command id. We override ActivatedAt below to handle activations.
      AddItem(0, label);
      const SkBitmap& node_icon = model_->GetFavicon(child);
      if (node_icon.width() > 0)
        SetIcon(GetItemCount() - 1, node_icon);
      // TODO(mdm): set up an observer to watch for icon load events and set
      // the icons in response.
    }
  }
}

void BookmarkNodeMenuModel::AddSubMenuForNode(const BookmarkNode* node) {
  DCHECK(node->is_folder());
  // Ironically the label will end up getting converted back to UTF8 later.
  const string16 label = UTF8ToUTF16(bookmark_utils::BuildMenuLabelFor(node));
  // Don't pass in the delegate, if any. Bookmark submenus don't need one.
  BookmarkNodeMenuModel* submenu =
      new BookmarkNodeMenuModel(NULL, model_, node, page_navigator_);
  // No command id. Nothing happens if you click on the submenu itself.
  AddSubMenu(0, label, submenu);
  submenus_.push_back(submenu);
}

void BookmarkNodeMenuModel::NavigateToMenuItem(
    int index,
    WindowOpenDisposition disposition) {
  const BookmarkNode* node = node_->GetChild(index);
  DCHECK(node);
  page_navigator_->OpenURL(OpenURLParams(
      node->url(), GURL(), disposition,
      content::PAGE_TRANSITION_AUTO_BOOKMARK,
      false));  // is_renderer_initiated
}

BookmarkSubMenuModel::BookmarkSubMenuModel(
    ui::SimpleMenuModel::Delegate* delegate,
    Browser* browser)
    : BookmarkNodeMenuModel(delegate, NULL, NULL, browser),
      browser_(browser),
      fixed_items_(0),
      bookmark_end_(0),
      menu_(NULL) {
}

BookmarkSubMenuModel::~BookmarkSubMenuModel() {
  if (model())
    model()->RemoveObserver(this);
}

void BookmarkSubMenuModel::BookmarkModelChanged() {
  if (menu_)
    menu_->Cancel();
}

void BookmarkSubMenuModel::BookmarkModelBeingDeleted(
    BookmarkModel* model) {
  set_model(NULL);
  // All our submenus will still have pointers to the model, but this call
  // should force the menu to close, which will cause them to be deleted.
  BookmarkModelChanged();
}

void BookmarkSubMenuModel::MenuWillShow() {
  Clear();
  AddCheckItemWithStringId(IDC_SHOW_BOOKMARK_BAR, IDS_SHOW_BOOKMARK_BAR);
  AddItemWithStringId(IDC_SHOW_BOOKMARK_MANAGER, IDS_BOOKMARK_MANAGER);
  AddItemWithStringId(IDC_IMPORT_SETTINGS, IDS_IMPORT_SETTINGS_MENU_LABEL);
  if (!model()) {
    set_model(browser_->profile()->GetBookmarkModel());
    if (model())
      model()->AddObserver(this);
  }
  if (!model()) {
    fixed_items_ = GetItemCount();
    bookmark_end_ = GetItemCount();
    return;
  }
  // The node count includes the node itself, so 1 means empty.
  if (model()->bookmark_bar_node()->GetTotalNodeCount() > 1) {
    AddSeparator();
    fixed_items_ = GetItemCount();
    if (!node())
      set_node(model()->bookmark_bar_node());
    // PopulateMenu() won't clear the items we added above.
    PopulateMenu();
  }
  bookmark_end_ = GetItemCount();
  if (model()->other_node()->GetTotalNodeCount() > 1) {
    AddSeparator();
    AddSubMenuForNode(model()->other_node());
  }
}

void BookmarkSubMenuModel::ActivatedAt(int index) {
  // Because this is also overridden in BookmarkNodeMenuModel which doesn't know
  // we might be prepending items, we have to adjust the index for it.
  if (index >= fixed_items_ && index < bookmark_end_)
    BookmarkNodeMenuModel::ActivatedAt(index - fixed_items_);
  else
    SimpleMenuModel::ActivatedAt(index);
}

void BookmarkSubMenuModel::ActivatedAt(int index, int event_flags) {
  // Because this is also overridden in BookmarkNodeMenuModel which doesn't know
  // we might be prepending items, we have to adjust the index for it.
  if (index >= fixed_items_ && index < bookmark_end_)
    BookmarkNodeMenuModel::ActivatedAt(index - fixed_items_, event_flags);
  else
    SimpleMenuModel::ActivatedAt(index, event_flags);
}

bool BookmarkSubMenuModel::IsEnabledAt(int index) const {
  // We don't want the delegate interfering with bookmark items.
  return index >= fixed_items_ || SimpleMenuModel::IsEnabledAt(index);
}

bool BookmarkSubMenuModel::IsVisibleAt(int index) const {
  // We don't want the delegate interfering with bookmark items.
  return index >= fixed_items_ || SimpleMenuModel::IsVisibleAt(index);
}
<commit_msg>Linux: fix crash when there are no bookmarks and an entry in the bookmark menu is used.<commit_after>// Copyright (c) 2011 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 "chrome/browser/ui/gtk/bookmark_sub_menu_model_gtk.h"

#include "base/stl_util.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/event_disposition.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h"
#include "chrome/browser/ui/gtk/menu_gtk.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

BookmarkNodeMenuModel::BookmarkNodeMenuModel(
    ui::SimpleMenuModel::Delegate* delegate,
    BookmarkModel* model,
    const BookmarkNode* node,
    PageNavigator* page_navigator)
    : SimpleMenuModel(delegate),
      model_(model),
      node_(node),
      page_navigator_(page_navigator) {
  DCHECK(page_navigator_);
}

BookmarkNodeMenuModel::~BookmarkNodeMenuModel() {
  Clear();
}

void BookmarkNodeMenuModel::Clear() {
  SimpleMenuModel::Clear();
  STLDeleteElements(&submenus_);
}

void BookmarkNodeMenuModel::MenuWillShow() {
  Clear();
  PopulateMenu();
}

void BookmarkNodeMenuModel::MenuClosed() {
  Clear();
}

void BookmarkNodeMenuModel::ActivatedAt(int index) {
  NavigateToMenuItem(index, CURRENT_TAB);
}

void BookmarkNodeMenuModel::ActivatedAt(int index, int event_flags) {
  NavigateToMenuItem(index, browser::DispositionFromEventFlags(event_flags));
}

void BookmarkNodeMenuModel::PopulateMenu() {
  DCHECK(submenus_.empty());
  for (int i = 0; i < node_->child_count(); ++i) {
    const BookmarkNode* child = node_->GetChild(i);
    if (child->is_folder()) {
      AddSubMenuForNode(child);
    } else {
      // Ironically the label will end up getting converted back to UTF8 later.
      const string16 label =
        UTF8ToUTF16(bookmark_utils::BuildMenuLabelFor(child));
      // No command id. We override ActivatedAt below to handle activations.
      AddItem(0, label);
      const SkBitmap& node_icon = model_->GetFavicon(child);
      if (node_icon.width() > 0)
        SetIcon(GetItemCount() - 1, node_icon);
      // TODO(mdm): set up an observer to watch for icon load events and set
      // the icons in response.
    }
  }
}

void BookmarkNodeMenuModel::AddSubMenuForNode(const BookmarkNode* node) {
  DCHECK(node->is_folder());
  // Ironically the label will end up getting converted back to UTF8 later.
  const string16 label = UTF8ToUTF16(bookmark_utils::BuildMenuLabelFor(node));
  // Don't pass in the delegate, if any. Bookmark submenus don't need one.
  BookmarkNodeMenuModel* submenu =
      new BookmarkNodeMenuModel(NULL, model_, node, page_navigator_);
  // No command id. Nothing happens if you click on the submenu itself.
  AddSubMenu(0, label, submenu);
  submenus_.push_back(submenu);
}

void BookmarkNodeMenuModel::NavigateToMenuItem(
    int index,
    WindowOpenDisposition disposition) {
  const BookmarkNode* node = node_->GetChild(index);
  DCHECK(node);
  page_navigator_->OpenURL(OpenURLParams(
      node->url(), GURL(), disposition,
      content::PAGE_TRANSITION_AUTO_BOOKMARK,
      false));  // is_renderer_initiated
}

BookmarkSubMenuModel::BookmarkSubMenuModel(
    ui::SimpleMenuModel::Delegate* delegate,
    Browser* browser)
    : BookmarkNodeMenuModel(delegate, NULL, NULL, browser),
      browser_(browser),
      fixed_items_(0),
      bookmark_end_(0),
      menu_(NULL) {
}

BookmarkSubMenuModel::~BookmarkSubMenuModel() {
  if (model())
    model()->RemoveObserver(this);
}

void BookmarkSubMenuModel::BookmarkModelChanged() {
  if (menu_)
    menu_->Cancel();
}

void BookmarkSubMenuModel::BookmarkModelBeingDeleted(
    BookmarkModel* model) {
  set_model(NULL);
  // All our submenus will still have pointers to the model, but this call
  // should force the menu to close, which will cause them to be deleted.
  BookmarkModelChanged();
}

void BookmarkSubMenuModel::MenuWillShow() {
  Clear();
  AddCheckItemWithStringId(IDC_SHOW_BOOKMARK_BAR, IDS_SHOW_BOOKMARK_BAR);
  AddItemWithStringId(IDC_SHOW_BOOKMARK_MANAGER, IDS_BOOKMARK_MANAGER);
  AddItemWithStringId(IDC_IMPORT_SETTINGS, IDS_IMPORT_SETTINGS_MENU_LABEL);
  fixed_items_ = bookmark_end_ = GetItemCount();
  if (!model()) {
    set_model(browser_->profile()->GetBookmarkModel());
    if (!model())
      return;
    model()->AddObserver(this);
  }
  // The node count includes the node itself, so 1 means empty.
  if (model()->bookmark_bar_node()->GetTotalNodeCount() > 1) {
    AddSeparator();
    fixed_items_ = GetItemCount();
    if (!node())
      set_node(model()->bookmark_bar_node());
    // PopulateMenu() won't clear the items we added above.
    PopulateMenu();
  }
  bookmark_end_ = GetItemCount();
  if (model()->other_node()->GetTotalNodeCount() > 1) {
    AddSeparator();
    AddSubMenuForNode(model()->other_node());
  }
}

void BookmarkSubMenuModel::ActivatedAt(int index) {
  // Because this is also overridden in BookmarkNodeMenuModel which doesn't know
  // we might be prepending items, we have to adjust the index for it.
  if (index >= fixed_items_ && index < bookmark_end_)
    BookmarkNodeMenuModel::ActivatedAt(index - fixed_items_);
  else
    SimpleMenuModel::ActivatedAt(index);
}

void BookmarkSubMenuModel::ActivatedAt(int index, int event_flags) {
  // Because this is also overridden in BookmarkNodeMenuModel which doesn't know
  // we might be prepending items, we have to adjust the index for it.
  if (index >= fixed_items_ && index < bookmark_end_)
    BookmarkNodeMenuModel::ActivatedAt(index - fixed_items_, event_flags);
  else
    SimpleMenuModel::ActivatedAt(index, event_flags);
}

bool BookmarkSubMenuModel::IsEnabledAt(int index) const {
  // We don't want the delegate interfering with bookmark items.
  return index >= fixed_items_ || SimpleMenuModel::IsEnabledAt(index);
}

bool BookmarkSubMenuModel::IsVisibleAt(int index) const {
  // We don't want the delegate interfering with bookmark items.
  return index >= fixed_items_ || SimpleMenuModel::IsVisibleAt(index);
}
<|endoftext|>