<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.

// Tests the MetricsService stat recording to make sure that the numbers are
// what we expect.

#include <string>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/pref_service_mock_builder.h"
#include "chrome/browser/prefs/pref_value_store.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/json_pref_store.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"

class MetricsServiceTest : public UITest {
 public:
  MetricsServiceTest() : UITest() {
    // We need to show the window so web content type tabs load.
    show_window_ = true;
  }

  // Open a few tabs of random content
  void OpenTabs() {
    scoped_refptr<BrowserProxy> window = automation()->GetBrowserWindow(0);
    ASSERT_TRUE(window.get());

    FilePath page1_path;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &page1_path));
    page1_path = page1_path.AppendASCII("title2.html");
    ASSERT_TRUE(window->AppendTab(net::FilePathToFileURL(page1_path)));

    FilePath page2_path;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &page2_path));
    page2_path = page2_path.AppendASCII("iframe.html");
    ASSERT_TRUE(window->AppendTab(net::FilePathToFileURL(page2_path)));
  }

  // Get a PrefService whose contents correspond to the Local State file
  // that was saved by the app as it closed.  The caller takes ownership of the
  // returned PrefService object.
  PrefService* GetLocalState() {
    FilePath path = user_data_dir().Append(chrome::kLocalStateFilename);
    return PrefServiceMockBuilder().WithUserFilePrefs(path).Create();
  }
};

TEST_F(MetricsServiceTest, CloseRenderersNormally) {
  OpenTabs();
  QuitBrowser();

  scoped_ptr<PrefService> local_state(GetLocalState());
  local_state->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true);
  local_state->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityPageLoadCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
  EXPECT_TRUE(local_state->GetBoolean(prefs::kStabilityExitedCleanly));
  EXPECT_EQ(1, local_state->GetInteger(prefs::kStabilityLaunchCount));
  EXPECT_EQ(3, local_state->GetInteger(prefs::kStabilityPageLoadCount));
  EXPECT_EQ(0, local_state->GetInteger(prefs::kStabilityRendererCrashCount));
}

TEST_F(MetricsServiceTest, DISABLED_CrashRenderers) {
  // This doesn't make sense to test in single process mode.
  if (ProxyLauncher::in_process_renderer())
    return;

  OpenTabs();

  {
    // Limit the lifetime of various automation proxies used here. We must
    // destroy them before calling QuitBrowser.

    scoped_refptr<BrowserProxy> window = automation()->GetBrowserWindow(0);
    ASSERT_TRUE(window.get());

    // Kill the process for one of the tabs.
    scoped_refptr<TabProxy> tab(window->GetTab(1));
    ASSERT_TRUE(tab.get());

    // We can get crash dumps on Windows always, Linux when breakpad is
    // enabled, and all platforms for official Google Chrome builds.
#if defined(OS_WIN) || defined(USE_LINUX_BREAKPAD) || \
    defined(GOOGLE_CHROME_BUILD)
    expected_crashes_ = 1;
#endif
    ASSERT_TRUE(tab->NavigateToURLAsync(GURL(chrome::kAboutCrashURL)));
  }

  // Give the browser a chance to notice the crashed tab.
  base::PlatformThread::Sleep(TestTimeouts::action_timeout_ms());

  QuitBrowser();

  scoped_ptr<PrefService> local_state(GetLocalState());
  local_state->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true);
  local_state->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityPageLoadCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
  EXPECT_TRUE(local_state->GetBoolean(prefs::kStabilityExitedCleanly));
  EXPECT_EQ(1, local_state->GetInteger(prefs::kStabilityLaunchCount));
  EXPECT_EQ(4, local_state->GetInteger(prefs::kStabilityPageLoadCount));
  EXPECT_EQ(1, local_state->GetInteger(prefs::kStabilityRendererCrashCount));
}
<commit_msg>Fix MetricsServiceTest.CloseRenderersNormally for touchui.<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.

// Tests the MetricsService stat recording to make sure that the numbers are
// what we expect.

#include <string>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/pref_service_mock_builder.h"
#include "chrome/browser/prefs/pref_value_store.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/json_pref_store.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"

class MetricsServiceTest : public UITest {
 public:
  MetricsServiceTest() : UITest() {
    // We need to show the window so web content type tabs load.
    show_window_ = true;
  }

  // Open a few tabs of random content
  void OpenTabs() {
    scoped_refptr<BrowserProxy> window = automation()->GetBrowserWindow(0);
    ASSERT_TRUE(window.get());

    FilePath page1_path;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &page1_path));
    page1_path = page1_path.AppendASCII("title2.html");
    ASSERT_TRUE(window->AppendTab(net::FilePathToFileURL(page1_path)));

    FilePath page2_path;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &page2_path));
    page2_path = page2_path.AppendASCII("iframe.html");
    ASSERT_TRUE(window->AppendTab(net::FilePathToFileURL(page2_path)));
  }

  // Get a PrefService whose contents correspond to the Local State file
  // that was saved by the app as it closed.  The caller takes ownership of the
  // returned PrefService object.
  PrefService* GetLocalState() {
    FilePath path = user_data_dir().Append(chrome::kLocalStateFilename);
    return PrefServiceMockBuilder().WithUserFilePrefs(path).Create();
  }
};

TEST_F(MetricsServiceTest, CloseRenderersNormally) {
  OpenTabs();
  QuitBrowser();

  scoped_ptr<PrefService> local_state(GetLocalState());
  local_state->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true);
  local_state->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityPageLoadCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
  EXPECT_TRUE(local_state->GetBoolean(prefs::kStabilityExitedCleanly));
  EXPECT_EQ(1, local_state->GetInteger(prefs::kStabilityLaunchCount));
#if defined(TOUCH_UI)
  // The keyboard page loads for touchui.
  EXPECT_EQ(4, local_state->GetInteger(prefs::kStabilityPageLoadCount));
#else
  EXPECT_EQ(3, local_state->GetInteger(prefs::kStabilityPageLoadCount));
#endif
  EXPECT_EQ(0, local_state->GetInteger(prefs::kStabilityRendererCrashCount));
}

TEST_F(MetricsServiceTest, DISABLED_CrashRenderers) {
  // This doesn't make sense to test in single process mode.
  if (ProxyLauncher::in_process_renderer())
    return;

  OpenTabs();

  {
    // Limit the lifetime of various automation proxies used here. We must
    // destroy them before calling QuitBrowser.

    scoped_refptr<BrowserProxy> window = automation()->GetBrowserWindow(0);
    ASSERT_TRUE(window.get());

    // Kill the process for one of the tabs.
    scoped_refptr<TabProxy> tab(window->GetTab(1));
    ASSERT_TRUE(tab.get());

    // We can get crash dumps on Windows always, Linux when breakpad is
    // enabled, and all platforms for official Google Chrome builds.
#if defined(OS_WIN) || defined(USE_LINUX_BREAKPAD) || \
    defined(GOOGLE_CHROME_BUILD)
    expected_crashes_ = 1;
#endif
    ASSERT_TRUE(tab->NavigateToURLAsync(GURL(chrome::kAboutCrashURL)));
  }

  // Give the browser a chance to notice the crashed tab.
  base::PlatformThread::Sleep(TestTimeouts::action_timeout_ms());

  QuitBrowser();

  scoped_ptr<PrefService> local_state(GetLocalState());
  local_state->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true);
  local_state->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityPageLoadCount, 0);
  local_state->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
  EXPECT_TRUE(local_state->GetBoolean(prefs::kStabilityExitedCleanly));
  EXPECT_EQ(1, local_state->GetInteger(prefs::kStabilityLaunchCount));
#if defined(TOUCH_UI)
  // The keyboard page loads for touchui.
  EXPECT_EQ(5, local_state->GetInteger(prefs::kStabilityPageLoadCount));
#else
  EXPECT_EQ(4, local_state->GetInteger(prefs::kStabilityPageLoadCount));
#endif
  EXPECT_EQ(1, local_state->GetInteger(prefs::kStabilityRendererCrashCount));
}
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2017-2019 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. 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 OWNER 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 <modules/base/processors/randomspheregenerator.h>
#include <inviwo/core/util/indexmapper.h>

#include <inviwo/core/interaction/events/pickingevent.h>
#include <inviwo/core/interaction/events/mouseevent.h>
#include <inviwo/core/interaction/events/touchevent.h>
#include <inviwo/core/interaction/events/wheelevent.h>
#include <inviwo/core/datastructures/geometry/mesh.h>
#include <inviwo/core/datastructures/buffer/bufferramprecision.h>
#include <inviwo/core/datastructures/buffer/buffer.h>
#include <inviwo/core/algorithm/boundingbox.h>

#include <numeric>

namespace inviwo {

// The Class Identifier has to be globally unique. Use a reverse DNS naming scheme
const ProcessorInfo RandomSphereGenerator::processorInfo_{
    "org.inviwo.RandomSphereGenerator",  // Class identifier
    "Random Sphere Generator",           // Display name
    "Mesh Creation",                     // Category
    CodeState::Stable,                   // Code state
    Tags::CPU,                           // Tags
};
const ProcessorInfo RandomSphereGenerator::getProcessorInfo() const { return processorInfo_; }

RandomSphereGenerator::RandomSphereGenerator()
    : Processor()
    , meshOut_("mesh")
    , seed_("seed", "Seed", 0, 0, std::mt19937::max())
    , reseed_("reseed_", "Seed")
    , scale_("scale", "Scale", 12.0f, 0.001f, 100.0f, 0.1f)
    , size_("size", "Size", 1.0f, 0.001f, 10.0f, 0.1f)
    , gridDim_("gridDim", "Grid Dimension", ivec3(12, 12, 12), ivec3(1), ivec3(128))
    , jigglePos_("jigglePos", "Jiggle Positions", true)
    , enablePicking_("enablePicking", "Enable Picking", false)
    , camera_("camera", "Camera", util::boundingBox(meshOut_))
    , spherePicking_(
          this, gridDim_.get().x * gridDim_.get().y * gridDim_.get().z, [&](PickingEvent* p) {
              handlePicking(p, [&](vec3 delta) {
                  if (positionBuffer_) {
                      auto& pos = positionBuffer_->getDataContainer();
                      pos[p->getPickedId()] += delta;
                      positionBuffer_->getOwner()->invalidateAllOther(positionBuffer_.get());
                  }
              });
          }) {
    addPort(meshOut_);

    addProperty(scale_);
    addProperty(size_);
    addProperty(gridDim_);
    addProperty(jigglePos_);

    addProperty(seed_);
    addProperty(reseed_);

    addProperty(enablePicking_);
    addProperty(camera_);
    camera_.setInvalidationLevel(InvalidationLevel::Valid);
    camera_.setCollapsed(true);

    seed_.setSemantics(PropertySemantics::Text);

    reseed_.onChange([&]() {
        seed_.set(static_cast<glm::i64>(rand(0.0f, static_cast<float>(seed_.getMaxValue()))));
        rand_.seed(static_cast<std::mt19937::result_type>(seed_.get()));
    });
}

void RandomSphereGenerator::process() {
    rand_.seed(static_cast<std::mt19937::result_type>(seed_.get()));

    const vec3 bboxMin(-scale_.get());
    const vec3 extent(scale_.get() * 2.0f);
    const vec3 delta(extent / vec3(gridDim_.get()));

    auto randPos = [&]() { return randVec3(-0.5f, 0.5f); };
    auto randColor = [&]() { return vec4(randVec3(0.5, 1.0), 1); };
    auto randRadius = [&]() { return size_.get() * rand(0.1f, 1.0f); };

    const bool dirty = seed_.isModified() || size_.isModified() || scale_.isModified() ||
                       enablePicking_.isModified();

    if (gridDim_.isModified() || dirty || !positionBuffer_) {
        const auto dim = gridDim_.get();
        const int numSpheres = dim.x * dim.y * dim.z;
        spherePicking_.resize(numSpheres);

        auto mesh = std::make_shared<Mesh>(DrawType::Points, ConnectivityType::None);

        auto vertexRAM = std::make_shared<BufferRAMPrecision<vec3>>(numSpheres);
        auto colorRAM = std::make_shared<BufferRAMPrecision<vec4>>(numSpheres);
        auto radiiRAM = std::make_shared<BufferRAMPrecision<float>>(numSpheres);

        // keep a reference to vertex position buffer for picking
        positionBuffer_ = vertexRAM;
        radiiBuffer_ = radiiRAM;

        mesh->addBuffer(Mesh::BufferInfo(BufferType::PositionAttrib),
                        std::make_shared<Buffer<vec3>>(vertexRAM));
        mesh->addBuffer(Mesh::BufferInfo(BufferType::ColorAttrib),
                        std::make_shared<Buffer<vec4>>(colorRAM));
        mesh->addBuffer(Mesh::BufferInfo(BufferType::RadiiAttrib),
                        std::make_shared<Buffer<float>>(radiiRAM));
        if (enablePicking_.get()) {
            auto pickingRAM = std::make_shared<BufferRAMPrecision<uint32_t>>(numSpheres);
            auto& data = pickingRAM->getDataContainer();
            // fill in picking IDs
            std::iota(data.begin(), data.end(),
                      static_cast<uint32_t>(spherePicking_.getPickingId(0)));

            mesh->addBuffer(Mesh::BufferInfo(BufferType::PickingAttrib),
                            std::make_shared<Buffer<uint32_t>>(pickingRAM));
        }

        auto& vertices = vertexRAM->getDataContainer();
        auto& colors = colorRAM->getDataContainer();
        auto& radii = radiiRAM->getDataContainer();

        util::IndexMapper<3, int> indexmapper(dim);
        if (jigglePos_.get()) {
            for (int i = 0; i < numSpheres; i++) {
                vertices[i] = (vec3(indexmapper(i)) + randPos()) * delta + bboxMin;
                colors[i] = randColor();
                radii[i] = randRadius();
            }
        } else {
            for (int i = 0; i < numSpheres; i++) {
                vertices[i] = vec3(indexmapper(i)) * delta + bboxMin;
                colors[i] = randColor();
                radii[i] = randRadius();
            }
        }
        meshOut_.setData(mesh);
    }
}

float RandomSphereGenerator::rand(const float min, const float max) const {
    return min + dis_(rand_) * (max - min);
}

vec3 RandomSphereGenerator::randVec3(const float min, const float max) const {
    float x = rand(min, max);
    float y = rand(min, max);
    float z = rand(min, max);
    return vec3(x, y, z);
}

vec3 RandomSphereGenerator::randVec3(const vec3& min, const vec3& max) const {
    float x = rand(min.x, max.x);
    float y = rand(min.y, max.y);
    float z = rand(min.z, max.z);
    return vec3(x, y, z);
}

void RandomSphereGenerator::handlePicking(PickingEvent* p, std::function<void(vec3)> callback) {
    if (enablePicking_) {
        if (p->getState() == PickingState::Updated &&
            p->getEvent()->hash() == MouseEvent::chash()) {
            auto me = p->getEventAs<MouseEvent>();
            if ((me->buttonState() & MouseButton::Left) && me->state() == MouseState::Move) {
                auto delta = getDelta(camera_, p);
                callback(delta);
                invalidate(InvalidationLevel::InvalidOutput);
                p->markAsUsed();
            }
        } else if (p->getState() == PickingState::Updated &&
                   p->getEvent()->hash() == TouchEvent::chash()) {

            auto te = p->getEventAs<TouchEvent>();
            if (!te->touchPoints().empty() && te->touchPoints()[0].state() == TouchState::Updated) {
                auto delta = getDelta(camera_, p);
                callback(delta);
                invalidate(InvalidationLevel::InvalidOutput);
                p->markAsUsed();
            }
        }
        else if (p->getState() == PickingState::Updated &&
            p->getEvent()->hash() == WheelEvent::chash()) {
            auto we = p->getEventAs<WheelEvent>();
            if (radiiBuffer_) {
                auto& radii = radiiBuffer_->getDataContainer();

                radii[p->getPickedId()] *= 1.0f - 0.05f * static_cast<float>(-we->delta().y);

                radiiBuffer_->getOwner()->invalidateAllOther(radiiBuffer_.get());
            }

            invalidate(InvalidationLevel::InvalidOutput);
            p->markAsUsed();
        }
    }
}

vec3 RandomSphereGenerator::getDelta(const Camera& camera, PickingEvent* p) {
    auto currNDC = p->getNDC();
    auto prevNDC = p->getPreviousNDC();

    // Use depth of initial press as reference to move in the image plane.
    auto refDepth = p->getPressedDepth();
    currNDC.z = refDepth;
    prevNDC.z = refDepth;

    auto corrWorld = camera.getWorldPosFromNormalizedDeviceCoords(static_cast<vec3>(currNDC));
    auto prevWorld = camera.getWorldPosFromNormalizedDeviceCoords(static_cast<vec3>(prevNDC));
    return (corrWorld - prevWorld);
}

}  // namespace inviwo
<commit_msg>Base: clang format<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2017-2019 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. 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 OWNER 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 <modules/base/processors/randomspheregenerator.h>
#include <inviwo/core/util/indexmapper.h>

#include <inviwo/core/interaction/events/pickingevent.h>
#include <inviwo/core/interaction/events/mouseevent.h>
#include <inviwo/core/interaction/events/touchevent.h>
#include <inviwo/core/interaction/events/wheelevent.h>
#include <inviwo/core/datastructures/geometry/mesh.h>
#include <inviwo/core/datastructures/buffer/bufferramprecision.h>
#include <inviwo/core/datastructures/buffer/buffer.h>
#include <inviwo/core/algorithm/boundingbox.h>

#include <numeric>

namespace inviwo {

// The Class Identifier has to be globally unique. Use a reverse DNS naming scheme
const ProcessorInfo RandomSphereGenerator::processorInfo_{
    "org.inviwo.RandomSphereGenerator",  // Class identifier
    "Random Sphere Generator",           // Display name
    "Mesh Creation",                     // Category
    CodeState::Stable,                   // Code state
    Tags::CPU,                           // Tags
};
const ProcessorInfo RandomSphereGenerator::getProcessorInfo() const { return processorInfo_; }

RandomSphereGenerator::RandomSphereGenerator()
    : Processor()
    , meshOut_("mesh")
    , seed_("seed", "Seed", 0, 0, std::mt19937::max())
    , reseed_("reseed_", "Seed")
    , scale_("scale", "Scale", 12.0f, 0.001f, 100.0f, 0.1f)
    , size_("size", "Size", 1.0f, 0.001f, 10.0f, 0.1f)
    , gridDim_("gridDim", "Grid Dimension", ivec3(12, 12, 12), ivec3(1), ivec3(128))
    , jigglePos_("jigglePos", "Jiggle Positions", true)
    , enablePicking_("enablePicking", "Enable Picking", false)
    , camera_("camera", "Camera", util::boundingBox(meshOut_))
    , spherePicking_(
          this, gridDim_.get().x * gridDim_.get().y * gridDim_.get().z, [&](PickingEvent* p) {
              handlePicking(p, [&](vec3 delta) {
                  if (positionBuffer_) {
                      auto& pos = positionBuffer_->getDataContainer();
                      pos[p->getPickedId()] += delta;
                      positionBuffer_->getOwner()->invalidateAllOther(positionBuffer_.get());
                  }
              });
          }) {
    addPort(meshOut_);

    addProperty(scale_);
    addProperty(size_);
    addProperty(gridDim_);
    addProperty(jigglePos_);

    addProperty(seed_);
    addProperty(reseed_);

    addProperty(enablePicking_);
    addProperty(camera_);
    camera_.setInvalidationLevel(InvalidationLevel::Valid);
    camera_.setCollapsed(true);

    seed_.setSemantics(PropertySemantics::Text);

    reseed_.onChange([&]() {
        seed_.set(static_cast<glm::i64>(rand(0.0f, static_cast<float>(seed_.getMaxValue()))));
        rand_.seed(static_cast<std::mt19937::result_type>(seed_.get()));
    });
}

void RandomSphereGenerator::process() {
    rand_.seed(static_cast<std::mt19937::result_type>(seed_.get()));

    const vec3 bboxMin(-scale_.get());
    const vec3 extent(scale_.get() * 2.0f);
    const vec3 delta(extent / vec3(gridDim_.get()));

    auto randPos = [&]() { return randVec3(-0.5f, 0.5f); };
    auto randColor = [&]() { return vec4(randVec3(0.5, 1.0), 1); };
    auto randRadius = [&]() { return size_.get() * rand(0.1f, 1.0f); };

    const bool dirty = seed_.isModified() || size_.isModified() || scale_.isModified() ||
                       enablePicking_.isModified();

    if (gridDim_.isModified() || dirty || !positionBuffer_) {
        const auto dim = gridDim_.get();
        const int numSpheres = dim.x * dim.y * dim.z;
        spherePicking_.resize(numSpheres);

        auto mesh = std::make_shared<Mesh>(DrawType::Points, ConnectivityType::None);

        auto vertexRAM = std::make_shared<BufferRAMPrecision<vec3>>(numSpheres);
        auto colorRAM = std::make_shared<BufferRAMPrecision<vec4>>(numSpheres);
        auto radiiRAM = std::make_shared<BufferRAMPrecision<float>>(numSpheres);

        // keep a reference to vertex position buffer for picking
        positionBuffer_ = vertexRAM;
        radiiBuffer_ = radiiRAM;

        mesh->addBuffer(Mesh::BufferInfo(BufferType::PositionAttrib),
                        std::make_shared<Buffer<vec3>>(vertexRAM));
        mesh->addBuffer(Mesh::BufferInfo(BufferType::ColorAttrib),
                        std::make_shared<Buffer<vec4>>(colorRAM));
        mesh->addBuffer(Mesh::BufferInfo(BufferType::RadiiAttrib),
                        std::make_shared<Buffer<float>>(radiiRAM));
        if (enablePicking_.get()) {
            auto pickingRAM = std::make_shared<BufferRAMPrecision<uint32_t>>(numSpheres);
            auto& data = pickingRAM->getDataContainer();
            // fill in picking IDs
            std::iota(data.begin(), data.end(),
                      static_cast<uint32_t>(spherePicking_.getPickingId(0)));

            mesh->addBuffer(Mesh::BufferInfo(BufferType::PickingAttrib),
                            std::make_shared<Buffer<uint32_t>>(pickingRAM));
        }

        auto& vertices = vertexRAM->getDataContainer();
        auto& colors = colorRAM->getDataContainer();
        auto& radii = radiiRAM->getDataContainer();

        util::IndexMapper<3, int> indexmapper(dim);
        if (jigglePos_.get()) {
            for (int i = 0; i < numSpheres; i++) {
                vertices[i] = (vec3(indexmapper(i)) + randPos()) * delta + bboxMin;
                colors[i] = randColor();
                radii[i] = randRadius();
            }
        } else {
            for (int i = 0; i < numSpheres; i++) {
                vertices[i] = vec3(indexmapper(i)) * delta + bboxMin;
                colors[i] = randColor();
                radii[i] = randRadius();
            }
        }
        meshOut_.setData(mesh);
    }
}

float RandomSphereGenerator::rand(const float min, const float max) const {
    return min + dis_(rand_) * (max - min);
}

vec3 RandomSphereGenerator::randVec3(const float min, const float max) const {
    float x = rand(min, max);
    float y = rand(min, max);
    float z = rand(min, max);
    return vec3(x, y, z);
}

vec3 RandomSphereGenerator::randVec3(const vec3& min, const vec3& max) const {
    float x = rand(min.x, max.x);
    float y = rand(min.y, max.y);
    float z = rand(min.z, max.z);
    return vec3(x, y, z);
}

void RandomSphereGenerator::handlePicking(PickingEvent* p, std::function<void(vec3)> callback) {
    if (enablePicking_) {
        if (p->getState() == PickingState::Updated &&
            p->getEvent()->hash() == MouseEvent::chash()) {
            auto me = p->getEventAs<MouseEvent>();
            if ((me->buttonState() & MouseButton::Left) && me->state() == MouseState::Move) {
                auto delta = getDelta(camera_, p);
                callback(delta);
                invalidate(InvalidationLevel::InvalidOutput);
                p->markAsUsed();
            }
        } else if (p->getState() == PickingState::Updated &&
                   p->getEvent()->hash() == TouchEvent::chash()) {

            auto te = p->getEventAs<TouchEvent>();
            if (!te->touchPoints().empty() && te->touchPoints()[0].state() == TouchState::Updated) {
                auto delta = getDelta(camera_, p);
                callback(delta);
                invalidate(InvalidationLevel::InvalidOutput);
                p->markAsUsed();
            }
        } else if (p->getState() == PickingState::Updated &&
                   p->getEvent()->hash() == WheelEvent::chash()) {
            auto we = p->getEventAs<WheelEvent>();
            if (radiiBuffer_) {
                auto& radii = radiiBuffer_->getDataContainer();

                radii[p->getPickedId()] *= 1.0f - 0.05f * static_cast<float>(-we->delta().y);

                radiiBuffer_->getOwner()->invalidateAllOther(radiiBuffer_.get());
            }

            invalidate(InvalidationLevel::InvalidOutput);
            p->markAsUsed();
        }
    }
}

vec3 RandomSphereGenerator::getDelta(const Camera& camera, PickingEvent* p) {
    auto currNDC = p->getNDC();
    auto prevNDC = p->getPreviousNDC();

    // Use depth of initial press as reference to move in the image plane.
    auto refDepth = p->getPressedDepth();
    currNDC.z = refDepth;
    prevNDC.z = refDepth;

    auto corrWorld = camera.getWorldPosFromNormalizedDeviceCoords(static_cast<vec3>(currNDC));
    auto prevWorld = camera.getWorldPosFromNormalizedDeviceCoords(static_cast<vec3>(prevNDC));
    return (corrWorld - prevWorld);
}

}  // namespace inviwo
<|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 "build/build_config.h"

// TODO(pkasting): Port Mac to use this.
#if defined(TOOLKIT_VIEWS) || defined(TOOLKIT_GTK)

#include "chrome/browser/tab_contents/infobar_container.h"

#include "chrome/browser/tab_contents/infobar.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"
#include "ui/base/animation/slide_animation.h"

InfoBarContainer::Delegate::~Delegate() {
}

InfoBarContainer::InfoBarContainer(Delegate* delegate)
    : delegate_(delegate),
      tab_contents_(NULL),
      top_arrow_target_height_(InfoBar::kDefaultArrowTargetHeight) {
}

InfoBarContainer::~InfoBarContainer() {
  // RemoveAllInfoBarsForDestruction() should have already cleared our infobars.
  DCHECK(infobars_.empty());
}

void InfoBarContainer::ChangeTabContents(TabContentsWrapper* contents) {
  registrar_.RemoveAll();

  while (!infobars_.empty()) {
    InfoBar* infobar = infobars_.front();
    // Inform the infobar that it's hidden.  If it was already closing, this
    // closes its delegate.
    infobar->Hide(false);
  }

  tab_contents_ = contents;
  if (tab_contents_) {
    Source<TabContentsWrapper> tc_source(tab_contents_);
    registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_ADDED,
                   tc_source);
    registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED,
                   tc_source);
    registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REPLACED,
                   tc_source);

    for (size_t i = 0; i < tab_contents_->infobar_count(); ++i) {
      // As when we removed the infobars above, we prevent callbacks to
      // OnInfoBarAnimated() for each infobar.
      AddInfoBar(
          tab_contents_->GetInfoBarDelegateAt(i)->CreateInfoBar(tab_contents_),
          i, false, NO_CALLBACK);
    }
  }

  // Now that everything is up to date, signal the delegate to re-layout.
  OnInfoBarStateChanged(false);
}

int InfoBarContainer::GetVerticalOverlap(int* total_height) {
  // Our |total_height| is the sum of the preferred heights of the InfoBars
  // contained within us plus the |vertical_overlap|.
  int vertical_overlap = 0;
  int next_infobar_y = 0;

  for (InfoBars::iterator i(infobars_.begin()); i != infobars_.end(); ++i) {
    InfoBar* infobar = *i;
    next_infobar_y -= infobar->arrow_height();
    vertical_overlap = std::max(vertical_overlap, -next_infobar_y);
    next_infobar_y += infobar->total_height();
  }

  if (total_height)
    *total_height = next_infobar_y + vertical_overlap;
  return vertical_overlap;
}

void InfoBarContainer::SetMaxTopArrowHeight(int height) {
  // Decrease the height by the arrow stroke thickness, which is the separator
  // line height, because the infobar arrow target heights are without-stroke.
  top_arrow_target_height_ = std::min(
      std::max(height - InfoBar::kSeparatorLineHeight, 0),
      InfoBar::kMaximumArrowTargetHeight);
  UpdateInfoBarArrowTargetHeights();
}

void InfoBarContainer::OnInfoBarStateChanged(bool is_animating) {
  if (delegate_)
    delegate_->InfoBarContainerStateChanged(is_animating);
  UpdateInfoBarArrowTargetHeights();
  PlatformSpecificInfoBarStateChanged(is_animating);
}

void InfoBarContainer::RemoveInfoBar(InfoBar* infobar) {
  infobar->set_container(NULL);
  InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar));
  DCHECK(i != infobars_.end());
  PlatformSpecificRemoveInfoBar(infobar);
  infobars_.erase(i);
}

void InfoBarContainer::RemoveAllInfoBarsForDestruction() {
  // Before we remove any children, we reset |delegate_|, so that no removals
  // will result in us trying to call
  // delegate_->InfoBarContainerStateChanged().  This is important because at
  // this point |delegate_| may be shutting down, and it's at best unimportant
  // and at worst disastrous to call that.
  delegate_ = NULL;

  // TODO(pkasting): Remove this once TabContentsWrapper calls CloseSoon().
  for (size_t i = infobars_.size(); i > 0; --i)
    infobars_[i]->CloseSoon();

  ChangeTabContents(NULL);
}

void InfoBarContainer::Observe(NotificationType type,
                               const NotificationSource& source,
                               const NotificationDetails& details) {
  switch (type.value) {
    case NotificationType::TAB_CONTENTS_INFOBAR_ADDED:
      AddInfoBar(
          Details<InfoBarAddedDetails>(details)->CreateInfoBar(tab_contents_),
          infobars_.size(), true, WANT_CALLBACK);
      break;

    case NotificationType::TAB_CONTENTS_INFOBAR_REMOVED: {
      InfoBarRemovedDetails* removed_details =
          Details<InfoBarRemovedDetails>(details).ptr();
      RemoveInfoBar(removed_details->first, removed_details->second);
      break;
    }

    case NotificationType::TAB_CONTENTS_INFOBAR_REPLACED: {
      InfoBarReplacedDetails* replaced_details =
          Details<InfoBarReplacedDetails>(details).ptr();
      AddInfoBar(replaced_details->second->CreateInfoBar(tab_contents_),
          RemoveInfoBar(replaced_details->first, false), false, WANT_CALLBACK);
      break;
    }

    default:
      NOTREACHED();
      break;
  }
}

size_t InfoBarContainer::RemoveInfoBar(InfoBarDelegate* delegate,
                                       bool use_animation) {
  // Search for the infobar associated with |delegate|.  We cannot search for
  // |delegate| in |tab_contents_|, because an InfoBar remains alive until its
  // close animation completes, while the delegate is removed from the tab
  // immediately.
  for (InfoBars::iterator i(infobars_.begin()); i != infobars_.end(); ++i) {
    InfoBar* infobar = *i;
    if (infobar->delegate() == delegate) {
      size_t position = i - infobars_.begin();
      // We merely need hide the infobar; it will call back to RemoveInfoBar()
      // itself once it's hidden.
      infobar->Hide(use_animation);
      infobar->CloseSoon();
      UpdateInfoBarArrowTargetHeights();
      return position;
    }
  }
  NOTREACHED();
  return infobars_.size();
}

void InfoBarContainer::AddInfoBar(InfoBar* infobar,
                                  size_t position,
                                  bool animate,
                                  CallbackStatus callback_status) {
  DCHECK(std::find(infobars_.begin(), infobars_.end(), infobar) ==
      infobars_.end());
  DCHECK_LE(position, infobars_.size());
  infobars_.insert(infobars_.begin() + position, infobar);
  UpdateInfoBarArrowTargetHeights();
  PlatformSpecificAddInfoBar(infobar, position);
  if (callback_status == WANT_CALLBACK)
    infobar->set_container(this);
  infobar->Show(animate);
  if (callback_status == NO_CALLBACK)
    infobar->set_container(this);
}

void InfoBarContainer::UpdateInfoBarArrowTargetHeights() {
  for (size_t i = 0; i < infobars_.size(); ++i)
    infobars_[i]->SetArrowTargetHeight(ArrowTargetHeightForInfoBar(i));
}

int InfoBarContainer::ArrowTargetHeightForInfoBar(size_t infobar_index) const {
  if (!delegate_->DrawInfoBarArrows(NULL))
    return 0;
  if (infobar_index == 0)
    return top_arrow_target_height_;
  const ui::SlideAnimation& first_infobar_animation =
      const_cast<const InfoBar*>(infobars_.front())->animation();
  if ((infobar_index > 1) || first_infobar_animation.IsShowing())
    return InfoBar::kDefaultArrowTargetHeight;
  // When the first infobar is animating closed, we animate the second infobar's
  // arrow target height from the default to the top target height.  Note that
  // the animation values here are going from 1.0 -> 0.0 as the top bar closes.
  return top_arrow_target_height_ + static_cast<int>(
      (InfoBar::kDefaultArrowTargetHeight - top_arrow_target_height_) *
          first_infobar_animation.GetCurrentValue());
}

#endif  // TOOLKIT_VIEWS || defined(TOOLKIT_GTK)
<commit_msg>Fix stupid off-by-one crash.<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 "build/build_config.h"

// TODO(pkasting): Port Mac to use this.
#if defined(TOOLKIT_VIEWS) || defined(TOOLKIT_GTK)

#include "chrome/browser/tab_contents/infobar_container.h"

#include "chrome/browser/tab_contents/infobar.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"
#include "ui/base/animation/slide_animation.h"

InfoBarContainer::Delegate::~Delegate() {
}

InfoBarContainer::InfoBarContainer(Delegate* delegate)
    : delegate_(delegate),
      tab_contents_(NULL),
      top_arrow_target_height_(InfoBar::kDefaultArrowTargetHeight) {
}

InfoBarContainer::~InfoBarContainer() {
  // RemoveAllInfoBarsForDestruction() should have already cleared our infobars.
  DCHECK(infobars_.empty());
}

void InfoBarContainer::ChangeTabContents(TabContentsWrapper* contents) {
  registrar_.RemoveAll();

  while (!infobars_.empty()) {
    InfoBar* infobar = infobars_.front();
    // Inform the infobar that it's hidden.  If it was already closing, this
    // closes its delegate.
    infobar->Hide(false);
  }

  tab_contents_ = contents;
  if (tab_contents_) {
    Source<TabContentsWrapper> tc_source(tab_contents_);
    registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_ADDED,
                   tc_source);
    registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED,
                   tc_source);
    registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REPLACED,
                   tc_source);

    for (size_t i = 0; i < tab_contents_->infobar_count(); ++i) {
      // As when we removed the infobars above, we prevent callbacks to
      // OnInfoBarAnimated() for each infobar.
      AddInfoBar(
          tab_contents_->GetInfoBarDelegateAt(i)->CreateInfoBar(tab_contents_),
          i, false, NO_CALLBACK);
    }
  }

  // Now that everything is up to date, signal the delegate to re-layout.
  OnInfoBarStateChanged(false);
}

int InfoBarContainer::GetVerticalOverlap(int* total_height) {
  // Our |total_height| is the sum of the preferred heights of the InfoBars
  // contained within us plus the |vertical_overlap|.
  int vertical_overlap = 0;
  int next_infobar_y = 0;

  for (InfoBars::iterator i(infobars_.begin()); i != infobars_.end(); ++i) {
    InfoBar* infobar = *i;
    next_infobar_y -= infobar->arrow_height();
    vertical_overlap = std::max(vertical_overlap, -next_infobar_y);
    next_infobar_y += infobar->total_height();
  }

  if (total_height)
    *total_height = next_infobar_y + vertical_overlap;
  return vertical_overlap;
}

void InfoBarContainer::SetMaxTopArrowHeight(int height) {
  // Decrease the height by the arrow stroke thickness, which is the separator
  // line height, because the infobar arrow target heights are without-stroke.
  top_arrow_target_height_ = std::min(
      std::max(height - InfoBar::kSeparatorLineHeight, 0),
      InfoBar::kMaximumArrowTargetHeight);
  UpdateInfoBarArrowTargetHeights();
}

void InfoBarContainer::OnInfoBarStateChanged(bool is_animating) {
  if (delegate_)
    delegate_->InfoBarContainerStateChanged(is_animating);
  UpdateInfoBarArrowTargetHeights();
  PlatformSpecificInfoBarStateChanged(is_animating);
}

void InfoBarContainer::RemoveInfoBar(InfoBar* infobar) {
  infobar->set_container(NULL);
  InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar));
  DCHECK(i != infobars_.end());
  PlatformSpecificRemoveInfoBar(infobar);
  infobars_.erase(i);
}

void InfoBarContainer::RemoveAllInfoBarsForDestruction() {
  // Before we remove any children, we reset |delegate_|, so that no removals
  // will result in us trying to call
  // delegate_->InfoBarContainerStateChanged().  This is important because at
  // this point |delegate_| may be shutting down, and it's at best unimportant
  // and at worst disastrous to call that.
  delegate_ = NULL;

  // TODO(pkasting): Remove this once TabContentsWrapper calls CloseSoon().
  for (size_t i = infobars_.size(); i > 0; --i)
    infobars_[i - 1]->CloseSoon();

  ChangeTabContents(NULL);
}

void InfoBarContainer::Observe(NotificationType type,
                               const NotificationSource& source,
                               const NotificationDetails& details) {
  switch (type.value) {
    case NotificationType::TAB_CONTENTS_INFOBAR_ADDED:
      AddInfoBar(
          Details<InfoBarAddedDetails>(details)->CreateInfoBar(tab_contents_),
          infobars_.size(), true, WANT_CALLBACK);
      break;

    case NotificationType::TAB_CONTENTS_INFOBAR_REMOVED: {
      InfoBarRemovedDetails* removed_details =
          Details<InfoBarRemovedDetails>(details).ptr();
      RemoveInfoBar(removed_details->first, removed_details->second);
      break;
    }

    case NotificationType::TAB_CONTENTS_INFOBAR_REPLACED: {
      InfoBarReplacedDetails* replaced_details =
          Details<InfoBarReplacedDetails>(details).ptr();
      AddInfoBar(replaced_details->second->CreateInfoBar(tab_contents_),
          RemoveInfoBar(replaced_details->first, false), false, WANT_CALLBACK);
      break;
    }

    default:
      NOTREACHED();
      break;
  }
}

size_t InfoBarContainer::RemoveInfoBar(InfoBarDelegate* delegate,
                                       bool use_animation) {
  // Search for the infobar associated with |delegate|.  We cannot search for
  // |delegate| in |tab_contents_|, because an InfoBar remains alive until its
  // close animation completes, while the delegate is removed from the tab
  // immediately.
  for (InfoBars::iterator i(infobars_.begin()); i != infobars_.end(); ++i) {
    InfoBar* infobar = *i;
    if (infobar->delegate() == delegate) {
      size_t position = i - infobars_.begin();
      // We merely need hide the infobar; it will call back to RemoveInfoBar()
      // itself once it's hidden.
      infobar->Hide(use_animation);
      infobar->CloseSoon();
      UpdateInfoBarArrowTargetHeights();
      return position;
    }
  }
  NOTREACHED();
  return infobars_.size();
}

void InfoBarContainer::AddInfoBar(InfoBar* infobar,
                                  size_t position,
                                  bool animate,
                                  CallbackStatus callback_status) {
  DCHECK(std::find(infobars_.begin(), infobars_.end(), infobar) ==
      infobars_.end());
  DCHECK_LE(position, infobars_.size());
  infobars_.insert(infobars_.begin() + position, infobar);
  UpdateInfoBarArrowTargetHeights();
  PlatformSpecificAddInfoBar(infobar, position);
  if (callback_status == WANT_CALLBACK)
    infobar->set_container(this);
  infobar->Show(animate);
  if (callback_status == NO_CALLBACK)
    infobar->set_container(this);
}

void InfoBarContainer::UpdateInfoBarArrowTargetHeights() {
  for (size_t i = 0; i < infobars_.size(); ++i)
    infobars_[i]->SetArrowTargetHeight(ArrowTargetHeightForInfoBar(i));
}

int InfoBarContainer::ArrowTargetHeightForInfoBar(size_t infobar_index) const {
  if (!delegate_->DrawInfoBarArrows(NULL))
    return 0;
  if (infobar_index == 0)
    return top_arrow_target_height_;
  const ui::SlideAnimation& first_infobar_animation =
      const_cast<const InfoBar*>(infobars_.front())->animation();
  if ((infobar_index > 1) || first_infobar_animation.IsShowing())
    return InfoBar::kDefaultArrowTargetHeight;
  // When the first infobar is animating closed, we animate the second infobar's
  // arrow target height from the default to the top target height.  Note that
  // the animation values here are going from 1.0 -> 0.0 as the top bar closes.
  return top_arrow_target_height_ + static_cast<int>(
      (InfoBar::kDefaultArrowTargetHeight - top_arrow_target_height_) *
          first_infobar_animation.GetCurrentValue());
}

#endif  // TOOLKIT_VIEWS || defined(TOOLKIT_GTK)
<|endoftext|>


<commit_before><commit_msg>Reverting 11277.<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ScrollHelper.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2005-09-23 12:23:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef DBAUI_SCROLLHELPER_HXX
#include "ScrollHelper.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#define LISTBOX_SCROLLING_AREA  12
namespace dbaui
{
DBG_NAME(OScrollHelper)

// -----------------------------------------------------------------------------

    OScrollHelper::OScrollHelper()
    {
        DBG_CTOR(OScrollHelper,NULL);
    }
    // -----------------------------------------------------------------------------
    OScrollHelper::~OScrollHelper()
    {

        DBG_DTOR(OScrollHelper,NULL);
    }
    // -----------------------------------------------------------------------------
    void OScrollHelper::scroll(const Point& _rPoint, const Size& _rOutputSize)
    {
        // Scrolling Areas
        Rectangle aScrollArea( Point(0, _rOutputSize.Height() - LISTBOX_SCROLLING_AREA),
                                     Size(_rOutputSize.Width(), LISTBOX_SCROLLING_AREA) );

        Link aToCall;
        // if pointer in bottom area begin scroll
        if( aScrollArea.IsInside(_rPoint) )
            aToCall = m_aUpScroll;
        else
        {
            aScrollArea.SetPos(Point(0,0));
            // if pointer in top area begin scroll
            if( aScrollArea.IsInside(_rPoint) )
                aToCall = m_aDownScroll;
        }
        if ( aToCall.IsSet() )
            aToCall.Call( NULL );
    }
    // -----------------------------------------------------------------------------
}
// -----------------------------------------------------------------------------

<commit_msg>INTEGRATION: CWS pchfix02 (1.4.178); FILE MERGED 2006/09/01 17:24:23 kaib 1.4.178.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ScrollHelper.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 07:00:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef DBAUI_SCROLLHELPER_HXX
#include "ScrollHelper.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#define LISTBOX_SCROLLING_AREA  12
namespace dbaui
{
DBG_NAME(OScrollHelper)

// -----------------------------------------------------------------------------

    OScrollHelper::OScrollHelper()
    {
        DBG_CTOR(OScrollHelper,NULL);
    }
    // -----------------------------------------------------------------------------
    OScrollHelper::~OScrollHelper()
    {

        DBG_DTOR(OScrollHelper,NULL);
    }
    // -----------------------------------------------------------------------------
    void OScrollHelper::scroll(const Point& _rPoint, const Size& _rOutputSize)
    {
        // Scrolling Areas
        Rectangle aScrollArea( Point(0, _rOutputSize.Height() - LISTBOX_SCROLLING_AREA),
                                     Size(_rOutputSize.Width(), LISTBOX_SCROLLING_AREA) );

        Link aToCall;
        // if pointer in bottom area begin scroll
        if( aScrollArea.IsInside(_rPoint) )
            aToCall = m_aUpScroll;
        else
        {
            aScrollArea.SetPos(Point(0,0));
            // if pointer in top area begin scroll
            if( aScrollArea.IsInside(_rPoint) )
                aToCall = m_aDownScroll;
        }
        if ( aToCall.IsSet() )
            aToCall.Call( NULL );
    }
    // -----------------------------------------------------------------------------
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before>//===- BitstreamReader.cpp - BitstreamReader implementation ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bitcode/BitstreamReader.h"

using namespace llvm;

//===----------------------------------------------------------------------===//
//  BitstreamCursor implementation
//===----------------------------------------------------------------------===//

void BitstreamCursor::freeState() {
  // Free all the Abbrevs.
  CurAbbrevs.clear();

  // Free all the Abbrevs in the block scope.
  BlockScope.clear();
}

/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
/// the block, and return true if the block has an error.
bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
  // Save the current block's state on BlockScope.
  BlockScope.push_back(Block(CurCodeSize));
  BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);

  // Add the abbrevs specific to this block to the CurAbbrevs list.
  if (const BitstreamReader::BlockInfo *Info =
      BitStream->getBlockInfo(BlockID)) {
    CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(),
                      Info->Abbrevs.end());
  }

  // Get the codesize of this block.
  CurCodeSize = ReadVBR(bitc::CodeLenWidth);
  SkipToFourByteBoundary();
  unsigned NumWords = Read(bitc::BlockSizeWidth);
  if (NumWordsP) *NumWordsP = NumWords;

  // Validate that this block is sane.
  if (CurCodeSize == 0 || AtEndOfStream())
    return true;

  return false;
}

void BitstreamCursor::readAbbreviatedLiteral(const BitCodeAbbrevOp &Op,
                                             SmallVectorImpl<uint64_t> &Vals) {
  assert(Op.isLiteral() && "Not a literal");
  // If the abbrev specifies the literal value to use, use it.
  Vals.push_back(Op.getLiteralValue());
}

void BitstreamCursor::readAbbreviatedField(const BitCodeAbbrevOp &Op,
                                           SmallVectorImpl<uint64_t> &Vals) {
  assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!");

  // Decode the value as we are commanded.
  switch (Op.getEncoding()) {
  case BitCodeAbbrevOp::Array:
  case BitCodeAbbrevOp::Blob:
    llvm_unreachable("Should not reach here");
  case BitCodeAbbrevOp::Fixed:
    Vals.push_back(Read((unsigned)Op.getEncodingData()));
    break;
  case BitCodeAbbrevOp::VBR:
    Vals.push_back(ReadVBR64((unsigned)Op.getEncodingData()));
    break;
  case BitCodeAbbrevOp::Char6:
    Vals.push_back(BitCodeAbbrevOp::DecodeChar6(Read(6)));
    break;
  }
}

void BitstreamCursor::skipAbbreviatedField(const BitCodeAbbrevOp &Op) {
  assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!");

  // Decode the value as we are commanded.
  switch (Op.getEncoding()) {
  case BitCodeAbbrevOp::Array:
  case BitCodeAbbrevOp::Blob:
    llvm_unreachable("Should not reach here");
  case BitCodeAbbrevOp::Fixed:
    (void)Read((unsigned)Op.getEncodingData());
    break;
  case BitCodeAbbrevOp::VBR:
    (void)ReadVBR64((unsigned)Op.getEncodingData());
    break;
  case BitCodeAbbrevOp::Char6:
    (void)Read(6);
    break;
  }
}

/// skipRecord - Read the current record and discard it.
void BitstreamCursor::skipRecord(unsigned AbbrevID) {
  // Skip unabbreviated records by reading past their entries.
  if (AbbrevID == bitc::UNABBREV_RECORD) {
    unsigned Code = ReadVBR(6);
    (void)Code;
    unsigned NumElts = ReadVBR(6);
    for (unsigned i = 0; i != NumElts; ++i)
      (void)ReadVBR64(6);
    return;
  }

  const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);

  for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
    const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
    if (Op.isLiteral())
      continue;

    if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
        Op.getEncoding() != BitCodeAbbrevOp::Blob) {
      skipAbbreviatedField(Op);
      continue;
    }

    if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
      // Array case.  Read the number of elements as a vbr6.
      unsigned NumElts = ReadVBR(6);

      // Get the element encoding.
      assert(i+2 == e && "array op not second to last?");
      const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);

      // Read all the elements.
      for (; NumElts; --NumElts)
        skipAbbreviatedField(EltEnc);
      continue;
    }

    assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
    // Blob case.  Read the number of bytes as a vbr6.
    unsigned NumElts = ReadVBR(6);
    SkipToFourByteBoundary();  // 32-bit alignment

    // Figure out where the end of this blob will be including tail padding.
    size_t NewEnd = GetCurrentBitNo()+((NumElts+3)&~3)*8;

    // If this would read off the end of the bitcode file, just set the
    // record to empty and return.
    if (!canSkipToPos(NewEnd/8)) {
      NextChar = BitStream->getBitcodeBytes().getExtent();
      break;
    }

    // Skip over the blob.
    JumpToBit(NewEnd);
  }
}

unsigned BitstreamCursor::readRecord(unsigned AbbrevID,
                                     SmallVectorImpl<uint64_t> &Vals,
                                     StringRef *Blob) {
  if (AbbrevID == bitc::UNABBREV_RECORD) {
    unsigned Code = ReadVBR(6);
    unsigned NumElts = ReadVBR(6);
    for (unsigned i = 0; i != NumElts; ++i)
      Vals.push_back(ReadVBR64(6));
    return Code;
  }

  const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);

  // Read the record code first.
  assert(Abbv->getNumOperandInfos() != 0 && "no record code in abbreviation?");
  const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
  if (CodeOp.isLiteral())
    readAbbreviatedLiteral(CodeOp, Vals);
  else
    readAbbreviatedField(CodeOp, Vals);
  unsigned Code = (unsigned)Vals.pop_back_val();

  for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) {
    const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
    if (Op.isLiteral()) {
      readAbbreviatedLiteral(Op, Vals);
      continue;
    }

    if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
        Op.getEncoding() != BitCodeAbbrevOp::Blob) {
      readAbbreviatedField(Op, Vals);
      continue;
    }

    if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
      // Array case.  Read the number of elements as a vbr6.
      unsigned NumElts = ReadVBR(6);

      // Get the element encoding.
      assert(i+2 == e && "array op not second to last?");
      const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);

      // Read all the elements.
      for (; NumElts; --NumElts)
        readAbbreviatedField(EltEnc, Vals);
      continue;
    }

    assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
    // Blob case.  Read the number of bytes as a vbr6.
    unsigned NumElts = ReadVBR(6);
    SkipToFourByteBoundary();  // 32-bit alignment

    // Figure out where the end of this blob will be including tail padding.
    size_t CurBitPos = GetCurrentBitNo();
    size_t NewEnd = CurBitPos+((NumElts+3)&~3)*8;

    // If this would read off the end of the bitcode file, just set the
    // record to empty and return.
    if (!canSkipToPos(NewEnd/8)) {
      Vals.append(NumElts, 0);
      NextChar = BitStream->getBitcodeBytes().getExtent();
      break;
    }

    // Otherwise, inform the streamer that we need these bytes in memory.
    const char *Ptr = (const char*)
      BitStream->getBitcodeBytes().getPointer(CurBitPos/8, NumElts);

    // If we can return a reference to the data, do so to avoid copying it.
    if (Blob) {
      *Blob = StringRef(Ptr, NumElts);
    } else {
      // Otherwise, unpack into Vals with zero extension.
      for (; NumElts; --NumElts)
        Vals.push_back((unsigned char)*Ptr++);
    }
    // Skip over tail padding.
    JumpToBit(NewEnd);
  }

  return Code;
}

void BitstreamCursor::ReadAbbrevRecord() {
  BitCodeAbbrev *Abbv = new BitCodeAbbrev();
  unsigned NumOpInfo = ReadVBR(5);
  for (unsigned i = 0; i != NumOpInfo; ++i) {
    bool IsLiteral = Read(1) ? true : false;
    if (IsLiteral) {
      Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8)));
      continue;
    }

    BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3);
    if (BitCodeAbbrevOp::hasEncodingData(E)) {
      unsigned Data = ReadVBR64(5);

      // As a special case, handle fixed(0) (i.e., a fixed field with zero bits)
      // and vbr(0) as a literal zero.  This is decoded the same way, and avoids
      // a slow path in Read() to have to handle reading zero bits.
      if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
          Data == 0) {
        Abbv->Add(BitCodeAbbrevOp(0));
        continue;
      }

      Abbv->Add(BitCodeAbbrevOp(E, Data));
    } else
      Abbv->Add(BitCodeAbbrevOp(E));
  }
  CurAbbrevs.push_back(Abbv);
}

bool BitstreamCursor::ReadBlockInfoBlock() {
  // If this is the second stream to get to the block info block, skip it.
  if (BitStream->hasBlockInfoRecords())
    return SkipBlock();

  if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true;

  SmallVector<uint64_t, 64> Record;
  BitstreamReader::BlockInfo *CurBlockInfo = nullptr;

  // Read all the records for this module.
  while (1) {
    BitstreamEntry Entry = advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs);

    switch (Entry.Kind) {
    case llvm::BitstreamEntry::SubBlock: // Handled for us already.
    case llvm::BitstreamEntry::Error:
      return true;
    case llvm::BitstreamEntry::EndBlock:
      return false;
    case llvm::BitstreamEntry::Record:
      // The interesting case.
      break;
    }

    // Read abbrev records, associate them with CurBID.
    if (Entry.ID == bitc::DEFINE_ABBREV) {
      if (!CurBlockInfo) return true;
      ReadAbbrevRecord();

      // ReadAbbrevRecord installs the abbrev in CurAbbrevs.  Move it to the
      // appropriate BlockInfo.
      CurBlockInfo->Abbrevs.push_back(std::move(CurAbbrevs.back()));
      CurAbbrevs.pop_back();
      continue;
    }

    // Read a record.
    Record.clear();
    switch (readRecord(Entry.ID, Record)) {
      default: break;  // Default behavior, ignore unknown content.
      case bitc::BLOCKINFO_CODE_SETBID:
        if (Record.size() < 1) return true;
        CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0]);
        break;
      case bitc::BLOCKINFO_CODE_BLOCKNAME: {
        if (!CurBlockInfo) return true;
        if (BitStream->isIgnoringBlockInfoNames()) break;  // Ignore name.
        std::string Name;
        for (unsigned i = 0, e = Record.size(); i != e; ++i)
          Name += (char)Record[i];
        CurBlockInfo->Name = Name;
        break;
      }
      case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
        if (!CurBlockInfo) return true;
        if (BitStream->isIgnoringBlockInfoNames()) break;  // Ignore name.
        std::string Name;
        for (unsigned i = 1, e = Record.size(); i != e; ++i)
          Name += (char)Record[i];
        CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0],
                                                           Name));
        break;
      }
    }
  }
}

<commit_msg>Factor out call to push_back. NFC.<commit_after>//===- BitstreamReader.cpp - BitstreamReader implementation ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bitcode/BitstreamReader.h"

using namespace llvm;

//===----------------------------------------------------------------------===//
//  BitstreamCursor implementation
//===----------------------------------------------------------------------===//

void BitstreamCursor::freeState() {
  // Free all the Abbrevs.
  CurAbbrevs.clear();

  // Free all the Abbrevs in the block scope.
  BlockScope.clear();
}

/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
/// the block, and return true if the block has an error.
bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
  // Save the current block's state on BlockScope.
  BlockScope.push_back(Block(CurCodeSize));
  BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);

  // Add the abbrevs specific to this block to the CurAbbrevs list.
  if (const BitstreamReader::BlockInfo *Info =
      BitStream->getBlockInfo(BlockID)) {
    CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(),
                      Info->Abbrevs.end());
  }

  // Get the codesize of this block.
  CurCodeSize = ReadVBR(bitc::CodeLenWidth);
  SkipToFourByteBoundary();
  unsigned NumWords = Read(bitc::BlockSizeWidth);
  if (NumWordsP) *NumWordsP = NumWords;

  // Validate that this block is sane.
  if (CurCodeSize == 0 || AtEndOfStream())
    return true;

  return false;
}

void BitstreamCursor::readAbbreviatedLiteral(const BitCodeAbbrevOp &Op,
                                             SmallVectorImpl<uint64_t> &Vals) {
  assert(Op.isLiteral() && "Not a literal");
  // If the abbrev specifies the literal value to use, use it.
  Vals.push_back(Op.getLiteralValue());
}

void BitstreamCursor::readAbbreviatedField(const BitCodeAbbrevOp &Op,
                                           SmallVectorImpl<uint64_t> &Vals) {
  assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!");

  // Decode the value as we are commanded.
  uint64_t Val;
  switch (Op.getEncoding()) {
  case BitCodeAbbrevOp::Array:
  case BitCodeAbbrevOp::Blob:
    llvm_unreachable("Should not reach here");
  case BitCodeAbbrevOp::Fixed:
    Val = Read((unsigned)Op.getEncodingData());
    break;
  case BitCodeAbbrevOp::VBR:
    Val = ReadVBR64((unsigned)Op.getEncodingData());
    break;
  case BitCodeAbbrevOp::Char6:
    Val = BitCodeAbbrevOp::DecodeChar6(Read(6));
    break;
  }
  Vals.push_back(Val);
}

void BitstreamCursor::skipAbbreviatedField(const BitCodeAbbrevOp &Op) {
  assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!");

  // Decode the value as we are commanded.
  switch (Op.getEncoding()) {
  case BitCodeAbbrevOp::Array:
  case BitCodeAbbrevOp::Blob:
    llvm_unreachable("Should not reach here");
  case BitCodeAbbrevOp::Fixed:
    (void)Read((unsigned)Op.getEncodingData());
    break;
  case BitCodeAbbrevOp::VBR:
    (void)ReadVBR64((unsigned)Op.getEncodingData());
    break;
  case BitCodeAbbrevOp::Char6:
    (void)Read(6);
    break;
  }
}

/// skipRecord - Read the current record and discard it.
void BitstreamCursor::skipRecord(unsigned AbbrevID) {
  // Skip unabbreviated records by reading past their entries.
  if (AbbrevID == bitc::UNABBREV_RECORD) {
    unsigned Code = ReadVBR(6);
    (void)Code;
    unsigned NumElts = ReadVBR(6);
    for (unsigned i = 0; i != NumElts; ++i)
      (void)ReadVBR64(6);
    return;
  }

  const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);

  for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
    const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
    if (Op.isLiteral())
      continue;

    if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
        Op.getEncoding() != BitCodeAbbrevOp::Blob) {
      skipAbbreviatedField(Op);
      continue;
    }

    if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
      // Array case.  Read the number of elements as a vbr6.
      unsigned NumElts = ReadVBR(6);

      // Get the element encoding.
      assert(i+2 == e && "array op not second to last?");
      const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);

      // Read all the elements.
      for (; NumElts; --NumElts)
        skipAbbreviatedField(EltEnc);
      continue;
    }

    assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
    // Blob case.  Read the number of bytes as a vbr6.
    unsigned NumElts = ReadVBR(6);
    SkipToFourByteBoundary();  // 32-bit alignment

    // Figure out where the end of this blob will be including tail padding.
    size_t NewEnd = GetCurrentBitNo()+((NumElts+3)&~3)*8;

    // If this would read off the end of the bitcode file, just set the
    // record to empty and return.
    if (!canSkipToPos(NewEnd/8)) {
      NextChar = BitStream->getBitcodeBytes().getExtent();
      break;
    }

    // Skip over the blob.
    JumpToBit(NewEnd);
  }
}

unsigned BitstreamCursor::readRecord(unsigned AbbrevID,
                                     SmallVectorImpl<uint64_t> &Vals,
                                     StringRef *Blob) {
  if (AbbrevID == bitc::UNABBREV_RECORD) {
    unsigned Code = ReadVBR(6);
    unsigned NumElts = ReadVBR(6);
    for (unsigned i = 0; i != NumElts; ++i)
      Vals.push_back(ReadVBR64(6));
    return Code;
  }

  const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);

  // Read the record code first.
  assert(Abbv->getNumOperandInfos() != 0 && "no record code in abbreviation?");
  const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
  if (CodeOp.isLiteral())
    readAbbreviatedLiteral(CodeOp, Vals);
  else
    readAbbreviatedField(CodeOp, Vals);
  unsigned Code = (unsigned)Vals.pop_back_val();

  for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) {
    const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
    if (Op.isLiteral()) {
      readAbbreviatedLiteral(Op, Vals);
      continue;
    }

    if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
        Op.getEncoding() != BitCodeAbbrevOp::Blob) {
      readAbbreviatedField(Op, Vals);
      continue;
    }

    if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
      // Array case.  Read the number of elements as a vbr6.
      unsigned NumElts = ReadVBR(6);

      // Get the element encoding.
      assert(i+2 == e && "array op not second to last?");
      const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);

      // Read all the elements.
      for (; NumElts; --NumElts)
        readAbbreviatedField(EltEnc, Vals);
      continue;
    }

    assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
    // Blob case.  Read the number of bytes as a vbr6.
    unsigned NumElts = ReadVBR(6);
    SkipToFourByteBoundary();  // 32-bit alignment

    // Figure out where the end of this blob will be including tail padding.
    size_t CurBitPos = GetCurrentBitNo();
    size_t NewEnd = CurBitPos+((NumElts+3)&~3)*8;

    // If this would read off the end of the bitcode file, just set the
    // record to empty and return.
    if (!canSkipToPos(NewEnd/8)) {
      Vals.append(NumElts, 0);
      NextChar = BitStream->getBitcodeBytes().getExtent();
      break;
    }

    // Otherwise, inform the streamer that we need these bytes in memory.
    const char *Ptr = (const char*)
      BitStream->getBitcodeBytes().getPointer(CurBitPos/8, NumElts);

    // If we can return a reference to the data, do so to avoid copying it.
    if (Blob) {
      *Blob = StringRef(Ptr, NumElts);
    } else {
      // Otherwise, unpack into Vals with zero extension.
      for (; NumElts; --NumElts)
        Vals.push_back((unsigned char)*Ptr++);
    }
    // Skip over tail padding.
    JumpToBit(NewEnd);
  }

  return Code;
}

void BitstreamCursor::ReadAbbrevRecord() {
  BitCodeAbbrev *Abbv = new BitCodeAbbrev();
  unsigned NumOpInfo = ReadVBR(5);
  for (unsigned i = 0; i != NumOpInfo; ++i) {
    bool IsLiteral = Read(1) ? true : false;
    if (IsLiteral) {
      Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8)));
      continue;
    }

    BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3);
    if (BitCodeAbbrevOp::hasEncodingData(E)) {
      unsigned Data = ReadVBR64(5);

      // As a special case, handle fixed(0) (i.e., a fixed field with zero bits)
      // and vbr(0) as a literal zero.  This is decoded the same way, and avoids
      // a slow path in Read() to have to handle reading zero bits.
      if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
          Data == 0) {
        Abbv->Add(BitCodeAbbrevOp(0));
        continue;
      }

      Abbv->Add(BitCodeAbbrevOp(E, Data));
    } else
      Abbv->Add(BitCodeAbbrevOp(E));
  }
  CurAbbrevs.push_back(Abbv);
}

bool BitstreamCursor::ReadBlockInfoBlock() {
  // If this is the second stream to get to the block info block, skip it.
  if (BitStream->hasBlockInfoRecords())
    return SkipBlock();

  if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true;

  SmallVector<uint64_t, 64> Record;
  BitstreamReader::BlockInfo *CurBlockInfo = nullptr;

  // Read all the records for this module.
  while (1) {
    BitstreamEntry Entry = advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs);

    switch (Entry.Kind) {
    case llvm::BitstreamEntry::SubBlock: // Handled for us already.
    case llvm::BitstreamEntry::Error:
      return true;
    case llvm::BitstreamEntry::EndBlock:
      return false;
    case llvm::BitstreamEntry::Record:
      // The interesting case.
      break;
    }

    // Read abbrev records, associate them with CurBID.
    if (Entry.ID == bitc::DEFINE_ABBREV) {
      if (!CurBlockInfo) return true;
      ReadAbbrevRecord();

      // ReadAbbrevRecord installs the abbrev in CurAbbrevs.  Move it to the
      // appropriate BlockInfo.
      CurBlockInfo->Abbrevs.push_back(std::move(CurAbbrevs.back()));
      CurAbbrevs.pop_back();
      continue;
    }

    // Read a record.
    Record.clear();
    switch (readRecord(Entry.ID, Record)) {
      default: break;  // Default behavior, ignore unknown content.
      case bitc::BLOCKINFO_CODE_SETBID:
        if (Record.size() < 1) return true;
        CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0]);
        break;
      case bitc::BLOCKINFO_CODE_BLOCKNAME: {
        if (!CurBlockInfo) return true;
        if (BitStream->isIgnoringBlockInfoNames()) break;  // Ignore name.
        std::string Name;
        for (unsigned i = 0, e = Record.size(); i != e; ++i)
          Name += (char)Record[i];
        CurBlockInfo->Name = Name;
        break;
      }
      case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
        if (!CurBlockInfo) return true;
        if (BitStream->isIgnoringBlockInfoNames()) break;  // Ignore name.
        std::string Name;
        for (unsigned i = 1, e = Record.size(); i != e; ++i)
          Name += (char)Record[i];
        CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0],
                                                           Name));
        break;
      }
    }
  }
}

<|endoftext|>


<commit_before>//! Copyright (c) 2013 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 <windows.h>
#include <stdio.h>
#include <stdarg.h>
#include "../el_io.h"

namespace el {

static inline int
ColorVfprintf(FILE* stream, int color, const char* format, va_list ap)
{
  HANDLE out_handle = GetStdHandle(STD_OUTPUT_HANDLE);
  CONSOLE_SCREEN_BUFFER_INFO info;
  GetConsoleScreenBufferInfo(out_handle, &info);
  WORD old_color = info.wAttributes;

  switch (color) {
  case COLOR_RED:
    color = FOREGROUND_INTENSITY | FOREGROUND_RED;
    break;
  case COLOR_GREEN:
    color = FOREGROUND_INTENSITY | FOREGROUND_GREEN;
    break;
  default:
    color = old_color;
  }

  SetConsoleTextAttribute(out_handle, (WORD)color);
  int ret = vfprintf(stream, format, ap);
  SetConsoleTextAttribute(out_handle, old_color);

  return ret;
}

int
ColorPrintf(int color, const char* format, ...)
{
  va_list ap;

  va_start(ap, format);
  int ret = ColorVfprintf(stdout, color, format, ap);
  va_end(ap);

  return ret;
}

int
ColorFprintf(FILE* stream, int color, const char* format, ...)
{
  va_list ap;

  va_start(ap, format);
  int ret = ColorVfprintf(stream, color, format, ap);
  va_end(ap);

  return ret;
}

}
<commit_msg>fixed bug of IO tools in windows platform<commit_after>//! Copyright (c) 2013 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 <windows.h>
#include <stdio.h>
#include <stdarg.h>
#include "../el_io.h"

namespace el {

static inline int
ColorVfprintf(FILE* stream, int color, const char* format, va_list ap)
{
  HANDLE out_handle = GetStdHandle(STD_OUTPUT_HANDLE);
  CONSOLE_SCREEN_BUFFER_INFO info;
  GetConsoleScreenBufferInfo(out_handle, &info);
  WORD old_color = info.wAttributes;

  switch (color) {
  case COLOR_RED:
    color = FOREGROUND_INTENSITY | FOREGROUND_RED;
    break;
  case COLOR_GREEN:
    color = FOREGROUND_INTENSITY | FOREGROUND_GREEN;
    break;
  default:
    color = old_color;
    break;
  }

  SetConsoleTextAttribute(out_handle, (WORD)color);
  int ret = vfprintf(stream, format, ap);
  SetConsoleTextAttribute(out_handle, old_color);

  return ret;
}

int
ColorPrintf(int color, const char* format, ...)
{
  va_list ap;

  va_start(ap, format);
  int ret = ColorVfprintf(stdout, color, format, ap);
  va_end(ap);

  return ret;
}

int
ColorFprintf(FILE* stream, int color, const char* format, ...)
{
  va_list ap;

  va_start(ap, format);
  int ret = ColorVfprintf(stream, color, format, ap);
  va_end(ap);

  return ret;
}

}
<|endoftext|>