<commit_before>/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "elf_file.h"

#include "common_compiler_test.h"
#include "oat.h"

namespace art {

class ElfWriterTest : public CommonCompilerTest {
 protected:
  virtual void SetUp() {
    ReserveImageSpace();
    CommonCompilerTest::SetUp();
  }
};

#define EXPECT_ELF_FILE_ADDRESS(ef, expected_value, symbol_name, build_map) \
  do { \
    void* addr = reinterpret_cast<void*>(ef->FindSymbolAddress(SHT_DYNSYM, \
                                                               symbol_name, \
                                                               build_map)); \
    EXPECT_NE(nullptr, addr); \
    EXPECT_LT(static_cast<uintptr_t>(ART_BASE_ADDRESS), reinterpret_cast<uintptr_t>(addr)); \
    if (expected_value == nullptr) { \
      expected_value = addr; \
    }                        \
    EXPECT_EQ(expected_value, addr); \
    EXPECT_EQ(expected_value, ef->FindDynamicSymbolAddress(symbol_name)); \
  } while (false)

TEST_F(ElfWriterTest, dlsym) {
  std::string elf_filename;
  if (IsHost()) {
    const char* host_dir = getenv("ANDROID_HOST_OUT");
    CHECK(host_dir != NULL);
    elf_filename = StringPrintf("%s/framework/core.oat", host_dir);
  } else {
    elf_filename = "/data/art-test/core.oat";
  }
  LOG(INFO) << "elf_filename=" << elf_filename;

  UnreserveImageSpace();
  void* dl_oatdata = NULL;
  void* dl_oatexec = NULL;
  void* dl_oatlastword = NULL;

#if defined(ART_USE_PORTABLE_COMPILER)
  {
    // We only use dlopen for loading with portable. See OatFile::Open.
    void* dl_oat_so = dlopen(elf_filename.c_str(), RTLD_NOW);
    ASSERT_TRUE(dl_oat_so != NULL) << dlerror();
    dl_oatdata = dlsym(dl_oat_so, "oatdata");
    ASSERT_TRUE(dl_oatdata != NULL);

    OatHeader* dl_oat_header = reinterpret_cast<OatHeader*>(dl_oatdata);
    ASSERT_TRUE(dl_oat_header->IsValid());
    dl_oatexec = dlsym(dl_oat_so, "oatexec");
    ASSERT_TRUE(dl_oatexec != NULL);
    ASSERT_LT(dl_oatdata, dl_oatexec);

    dl_oatlastword = dlsym(dl_oat_so, "oatlastword");
    ASSERT_TRUE(dl_oatlastword != NULL);
    ASSERT_LT(dl_oatexec, dl_oatlastword);

    ASSERT_EQ(0, dlclose(dl_oat_so));
  }
#endif

  UniquePtr<File> file(OS::OpenFileForReading(elf_filename.c_str()));
  ASSERT_TRUE(file.get() != NULL);
  {
    std::string error_msg;
    UniquePtr<ElfFile> ef(ElfFile::Open(file.get(), false, false, &error_msg));
    CHECK(ef.get() != nullptr) << error_msg;
    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatdata, "oatdata", false);
    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatexec, "oatexec", false);
    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatlastword, "oatlastword", false);
  }
  {
    std::string error_msg;
    UniquePtr<ElfFile> ef(ElfFile::Open(file.get(), false, false, &error_msg));
    CHECK(ef.get() != nullptr) << error_msg;
    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatdata, "oatdata", true);
    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatexec, "oatexec", true);
    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatlastword, "oatlastword", true);
  }
  {
    std::string error_msg;
    UniquePtr<ElfFile> ef(ElfFile::Open(file.get(), false, true, &error_msg));
    CHECK(ef.get() != nullptr) << error_msg;
    CHECK(ef->Load(false, &error_msg)) << error_msg;
    EXPECT_EQ(dl_oatdata, ef->FindDynamicSymbolAddress("oatdata"));
    EXPECT_EQ(dl_oatexec, ef->FindDynamicSymbolAddress("oatexec"));
    EXPECT_EQ(dl_oatlastword, ef->FindDynamicSymbolAddress("oatlastword"));
  }
}

}  // namespace art
<commit_msg>Fix elf_writer_test for 64b target<commit_after>/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "elf_file.h"

#include "common_compiler_test.h"
#include "oat.h"

namespace art {

class ElfWriterTest : public CommonCompilerTest {
 protected:
  virtual void SetUp() {
    ReserveImageSpace();
    CommonCompilerTest::SetUp();
  }
};

#define EXPECT_ELF_FILE_ADDRESS(ef, expected_value, symbol_name, build_map) \
  do { \
    void* addr = reinterpret_cast<void*>(ef->FindSymbolAddress(SHT_DYNSYM, \
                                                               symbol_name, \
                                                               build_map)); \
    EXPECT_NE(nullptr, addr); \
    EXPECT_LT(static_cast<uintptr_t>(ART_BASE_ADDRESS), reinterpret_cast<uintptr_t>(addr)); \
    if (expected_value == nullptr) { \
      expected_value = addr; \
    }                        \
    EXPECT_EQ(expected_value, addr); \
    EXPECT_EQ(expected_value, ef->FindDynamicSymbolAddress(symbol_name)); \
  } while (false)

TEST_F(ElfWriterTest, dlsym) {
  std::string elf_filename;
  if (IsHost()) {
    const char* host_dir = getenv("ANDROID_HOST_OUT");
    CHECK(host_dir != NULL);
    elf_filename = StringPrintf("%s/framework/core.oat", host_dir);
  } else {
#ifdef __LP64__
    elf_filename = "/data/art-test64/core.oat";
#else
    elf_filename = "/data/art-test/core.oat";
#endif
  }
  LOG(INFO) << "elf_filename=" << elf_filename;

  UnreserveImageSpace();
  void* dl_oatdata = NULL;
  void* dl_oatexec = NULL;
  void* dl_oatlastword = NULL;

#if defined(ART_USE_PORTABLE_COMPILER)
  {
    // We only use dlopen for loading with portable. See OatFile::Open.
    void* dl_oat_so = dlopen(elf_filename.c_str(), RTLD_NOW);
    ASSERT_TRUE(dl_oat_so != NULL) << dlerror();
    dl_oatdata = dlsym(dl_oat_so, "oatdata");
    ASSERT_TRUE(dl_oatdata != NULL);

    OatHeader* dl_oat_header = reinterpret_cast<OatHeader*>(dl_oatdata);
    ASSERT_TRUE(dl_oat_header->IsValid());
    dl_oatexec = dlsym(dl_oat_so, "oatexec");
    ASSERT_TRUE(dl_oatexec != NULL);
    ASSERT_LT(dl_oatdata, dl_oatexec);

    dl_oatlastword = dlsym(dl_oat_so, "oatlastword");
    ASSERT_TRUE(dl_oatlastword != NULL);
    ASSERT_LT(dl_oatexec, dl_oatlastword);

    ASSERT_EQ(0, dlclose(dl_oat_so));
  }
#endif

  UniquePtr<File> file(OS::OpenFileForReading(elf_filename.c_str()));
  ASSERT_TRUE(file.get() != NULL);
  {
    std::string error_msg;
    UniquePtr<ElfFile> ef(ElfFile::Open(file.get(), false, false, &error_msg));
    CHECK(ef.get() != nullptr) << error_msg;
    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatdata, "oatdata", false);
    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatexec, "oatexec", false);
    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatlastword, "oatlastword", false);
  }
  {
    std::string error_msg;
    UniquePtr<ElfFile> ef(ElfFile::Open(file.get(), false, false, &error_msg));
    CHECK(ef.get() != nullptr) << error_msg;
    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatdata, "oatdata", true);
    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatexec, "oatexec", true);
    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatlastword, "oatlastword", true);
  }
  {
    std::string error_msg;
    UniquePtr<ElfFile> ef(ElfFile::Open(file.get(), false, true, &error_msg));
    CHECK(ef.get() != nullptr) << error_msg;
    CHECK(ef->Load(false, &error_msg)) << error_msg;
    EXPECT_EQ(dl_oatdata, ef->FindDynamicSymbolAddress("oatdata"));
    EXPECT_EQ(dl_oatexec, ef->FindDynamicSymbolAddress("oatexec"));
    EXPECT_EQ(dl_oatlastword, ef->FindDynamicSymbolAddress("oatlastword"));
  }
}

}  // namespace art
<|endoftext|>


<commit_before>#include <ROOT/TDataFrame.hxx>
#include <ROOT/TTrivialDS.hxx>
#include <ROOT/TSeq.hxx>

#include "gtest/gtest.h"

using namespace ROOT::Experimental;
using namespace ROOT::Experimental::TDF;

TEST(TTrivialDS, ColTypeNames)
{
   TTrivialDS tds(32);
   tds.SetNSlots(1);

   auto colName = tds.GetColumnNames()[0]; // We know it's one.
   EXPECT_STREQ("col0", colName.c_str());
   EXPECT_STREQ("ULong64_t", tds.GetTypeName("col0").c_str());

   EXPECT_TRUE(tds.HasColumn("col0"));
   EXPECT_FALSE(tds.HasColumn("col1"));
}

TEST(TTrivialDS, EntryRanges)
{
   TTrivialDS tds(32);
   const auto nSlots = 4U;
   tds.SetNSlots(nSlots);

   auto ranges = tds.GetEntryRanges();

   EXPECT_EQ(4U, ranges.size());
   EXPECT_EQ(0U, ranges[0].first);
   EXPECT_EQ(8U, ranges[0].second);
   EXPECT_EQ(8U, ranges[1].first);
   EXPECT_EQ(16U, ranges[1].second);
   EXPECT_EQ(16U, ranges[2].first);
   EXPECT_EQ(24U, ranges[2].second);
   EXPECT_EQ(24U, ranges[3].first);
   EXPECT_EQ(32U, ranges[3].second);
}

TEST(TTrivialDS, ColumnReaders)
{
   TTrivialDS tds(32);
   const auto nSlots = 4U;
   tds.SetNSlots(nSlots);
   auto vals = tds.GetColumnReaders<ULong64_t>("col0");
   auto ranges = tds.GetEntryRanges();
   auto slot = 0U;
   for (auto &&range : ranges) {
      for (auto i : ROOT::TSeq<ULong64_t>(range.first, range.second)) {
         tds.SetEntry(slot, i);
         auto val = **vals[slot];
         EXPECT_EQ(i, val);
      }
      slot++;
   }
}

#ifndef NDEBUG
TEST(TTrivialDS, SetNSlotsTwice)
{
   auto theTest = []() {
      TTrivialDS tds(1);
      tds.SetNSlots(1);
      tds.SetNSlots(1);
   };
   ASSERT_DEATH(theTest(), "Setting the number of slots even if the number of slots is different from zero.");
}
#endif

TEST(TTrivialDS, FromATDF)
{
   std::unique_ptr<TDataSource> tds(new TTrivialDS(32));
   TDataFrame tdf(std::move(tds));
   auto max = tdf.Max<ULong64_t>("col0");
   auto min = tdf.Min<ULong64_t>("col0");
   auto c = tdf.Count();

   EXPECT_EQ(32U, *c);
   EXPECT_DOUBLE_EQ(31., *max);
   EXPECT_DOUBLE_EQ(0., *min);
}

TEST(TTrivialDS, FromATDFWithJitting)
{
   std::unique_ptr<TDataSource> tds(new TTrivialDS(32));
   TDataFrame tdf(std::move(tds));
   auto max = tdf.Filter("col0 < 10").Max("col0");
   auto min = tdf.Filter("col0 > 10").Define("j", "col0*2").Min("j");

   EXPECT_DOUBLE_EQ(9., *max);
   EXPECT_DOUBLE_EQ(22., *min);
}
<commit_msg>[TDF] Also test Filter/Define for the trivial data-source<commit_after>#include <ROOT/TDataFrame.hxx>
#include <ROOT/TTrivialDS.hxx>
#include <ROOT/TSeq.hxx>

#include "gtest/gtest.h"

using namespace ROOT::Experimental;
using namespace ROOT::Experimental::TDF;

TEST(TTrivialDS, ColTypeNames)
{
   TTrivialDS tds(32);
   tds.SetNSlots(1);

   auto colName = tds.GetColumnNames()[0]; // We know it's one.
   EXPECT_STREQ("col0", colName.c_str());
   EXPECT_STREQ("ULong64_t", tds.GetTypeName("col0").c_str());

   EXPECT_TRUE(tds.HasColumn("col0"));
   EXPECT_FALSE(tds.HasColumn("col1"));
}

TEST(TTrivialDS, EntryRanges)
{
   TTrivialDS tds(32);
   const auto nSlots = 4U;
   tds.SetNSlots(nSlots);

   auto ranges = tds.GetEntryRanges();

   EXPECT_EQ(4U, ranges.size());
   EXPECT_EQ(0U, ranges[0].first);
   EXPECT_EQ(8U, ranges[0].second);
   EXPECT_EQ(8U, ranges[1].first);
   EXPECT_EQ(16U, ranges[1].second);
   EXPECT_EQ(16U, ranges[2].first);
   EXPECT_EQ(24U, ranges[2].second);
   EXPECT_EQ(24U, ranges[3].first);
   EXPECT_EQ(32U, ranges[3].second);
}

TEST(TTrivialDS, ColumnReaders)
{
   TTrivialDS tds(32);
   const auto nSlots = 4U;
   tds.SetNSlots(nSlots);
   auto vals = tds.GetColumnReaders<ULong64_t>("col0");
   auto ranges = tds.GetEntryRanges();
   auto slot = 0U;
   for (auto &&range : ranges) {
      for (auto i : ROOT::TSeq<ULong64_t>(range.first, range.second)) {
         tds.SetEntry(slot, i);
         auto val = **vals[slot];
         EXPECT_EQ(i, val);
      }
      slot++;
   }
}

#ifndef NDEBUG
TEST(TTrivialDS, SetNSlotsTwice)
{
   auto theTest = []() {
      TTrivialDS tds(1);
      tds.SetNSlots(1);
      tds.SetNSlots(1);
   };
   ASSERT_DEATH(theTest(), "Setting the number of slots even if the number of slots is different from zero.");
}
#endif

TEST(TTrivialDS, FromATDF)
{
   std::unique_ptr<TDataSource> tds(new TTrivialDS(32));
   TDataFrame tdf(std::move(tds));
   auto max = tdf.Max<ULong64_t>("col0");
   auto min = tdf.Min<ULong64_t>("col0");
   auto c = tdf.Count();
   auto max2 = tdf.Filter([](ULong64_t col0) { return col0 < 10; }, {"col0"}).Max<ULong64_t>("col0");
   auto min2 = tdf.Filter([](ULong64_t col0) { return col0 > 10; }, {"col0"})
                  .Define("j", [](ULong64_t col0) { return col0 * 2; }, {"col0"})
                  .Min<ULong64_t>("j");

   EXPECT_EQ(32U, *c);
   EXPECT_DOUBLE_EQ(31., *max);
   EXPECT_DOUBLE_EQ(0., *min);
   EXPECT_DOUBLE_EQ(9., *max2);
   EXPECT_DOUBLE_EQ(22., *min2);
}

TEST(TTrivialDS, FromATDFWithJitting)
{
   std::unique_ptr<TDataSource> tds(new TTrivialDS(32));
   TDataFrame tdf(std::move(tds));
   auto max = tdf.Filter("col0 < 10").Max("col0");
   auto min = tdf.Filter("col0 > 10").Define("j", "col0*2").Min("j");

   EXPECT_DOUBLE_EQ(9., *max);
   EXPECT_DOUBLE_EQ(22., *min);
}
<|endoftext|>


<commit_before>
#include <string>

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <reflectionzeug/Property.h>
#include <reflectionzeug/PropertyGroup.h>
#include <reflectionzeug/PropertySerializer.h>
#include <reflectionzeug/PropertyDeserializer.h>
#include <propertyguizeug/PropertyBrowser.h>

#include "libzeug-version.h"

#include "Switch.h"

#ifdef WIN32
#define SETTINGS_PATH ".\\data\\propertygui.ini"
#else
#define SETTINGS_PATH "./data/propertygui.ini"
#endif

using namespace reflectionzeug;
using namespace propertyguizeug;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QApplication::setApplicationName("propertygui-example");
    QApplication::setOrganizationName(META_AUTHOR_ORGANIZATION);

    auto * widget = new QWidget();
    widget->setMinimumWidth(200);
    widget->setMaximumWidth(640);
    widget->setMinimumHeight(200);
    widget->setMaximumHeight(460);
    widget->setWindowTitle("Property Example");
    widget->setAutoFillBackground(true);

    auto * settings = new PropertyGroup("Settings");

    auto * visible = settings->addProperty<bool>("Visible",
        [widget]() {
            return widget->isVisible();
        },
        [widget](const bool & b) {
            widget->setVisible(b);
        });

    visible->setOption("tooltip", "Opens and closes the example window.");

    PropertyGroup * size = settings->addGroup("Size");

    auto * width = size->addProperty<int>("Width",
        [widget] () -> int {
            return widget->width();
        },
        [widget] (const int & width) {
            widget->resize(width, widget->height());
        });

    width->setOption("minimum", widget->minimumWidth());
    width->setOption("maximum", widget->maximumWidth());
    width->setOption("suffix", " pixel");

    auto * height = size->addProperty<int>("Height",
        [widget] () -> int {
            return widget->height();
        },
        [widget] (const int & height) {
            widget->resize(widget->width(), height);
        });

    height->setOption("minimum", widget->minimumHeight());
    height->setOption("maximum", widget->maximumHeight());
    height->setOption("suffix", " pixel");

    auto * aspect = size->addProperty<float>("Aspect",
        [widget] () -> float {
            return static_cast<float>(widget->width()) / widget->height();
        },
        [widget] (const float & aspect) {
            int width = static_cast<int>(aspect * widget->height());
            widget->resize(width, widget->height());
        });
    aspect->setOption("step", 0.1f);
    aspect->setOption("suffix", " w/h");
    aspect->setOption("precision", 4);

    auto * minimumSize = size->addProperty<std::array<int, 2>>("minimumSize",
        [widget] (size_t i) -> int {
            switch (i)
            {
            case 0:
                return widget->minimumWidth();
            case 1:
                return widget->minimumHeight();
            default:
                return -1;
            }
        },
        [widget, width, height] (size_t i, const int & size) {
            switch (i)
            {
            case 0:
                widget->setMinimumWidth(size);
                width->setOption("minimum", size);
                break;
            case 1:
                widget->setMinimumHeight(size);
                height->setOption("minimum", size);

            }
        });

    minimumSize->setOption("title", "Minimum Size");

    auto * maximumSize = size->addProperty<std::array<int, 2>>("maximumSize",
        [widget](size_t i) -> int {
            switch (i)
            {
            case 0:
                return widget->maximumWidth();
            case 1:
                return widget->maximumHeight();
            default:
                return -1;

            }
        },
        [widget, width, height] (size_t i, const int & size) {
            switch (i)
            {
            case 0:
                widget->setMaximumWidth(size);
                width->setOption("maximum", size);
                break;
            case 1:
                widget->setMaximumHeight(size);
                height->setOption("maximum", size);
            }
        });

    maximumSize->setOption("title", "Maximum Size");

    auto * windowTitle = settings->addProperty<std::string>("windowTitle",
        [widget]() {
            return widget->windowTitle().toStdString();
        },
        [widget](const std::string & title) {
            widget->setWindowTitle(QString::fromStdString(title));
        });

    windowTitle->setOption("title", "Window Title");

    auto * backgroundColor = settings->addProperty<Color>("backgroundColor",
        [widget]() {
            QColor qcolor = widget->palette().color(QPalette::Window);
            return Color(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha());
        },
        [widget](const Color & color) {
            QColor qcolor(color.red(), color.green(), color.blue(), color.alpha());
            QPalette palette;
            palette.setColor(QPalette::Window, qcolor);
            widget->setPalette(palette);
        });

    backgroundColor->setOption("title", "Background Color");
    backgroundColor->setOption("tooltip", "Sets the background color of the example window.");

    auto * cursorProperty = settings->addProperty<Qt::CursorShape>("Cursor",
        [widget] ()
        {
            return widget->cursor().shape();
        },
        [widget] (const Qt::CursorShape & shape)
        {
            widget->setCursor(QCursor(shape));
        });

    cursorProperty->setStrings({
        { Qt::PointingHandCursor, "Pointing Hand Cursor" },
        { Qt::BusyCursor, "Busy Cursor" },
        { Qt::ArrowCursor, "Arrow Cursor" },
        { Qt::WaitCursor, "Wait Cursor" }
    });

    Property<FilePath> * filePath = settings->addProperty<FilePath>("filePath", "");
    filePath->setOption("uniqueidentifier", "settings/filePath");
    filePath->setOption("tooltip", "A file path with no meaning.");

    QPushButton button("Add");

    QObject::connect(&button, &QAbstractButton::pressed, [settings] ()
        {
            static int i = 0;
            settings->addProperty<int>("_" + std::to_string(i++), 12);
        });

    button.show();

    PropertyDeserializer deserializer;
    deserializer.deserialize(*settings, SETTINGS_PATH);

    auto * browser = new PropertyBrowser(settings);
    browser->show();

    int result = a.exec();

    PropertySerializer serializer;
    serializer.serialize(*settings, SETTINGS_PATH);

    delete settings;
    delete browser;
    delete widget;

    return result;
}
<commit_msg>Update propertyguiexample<commit_after>
#include <string>

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <reflectionzeug/Property.h>
#include <reflectionzeug/PropertyGroup.h>
#include <reflectionzeug/PropertySerializer.h>
#include <reflectionzeug/PropertyDeserializer.h>
#include <propertyguizeug/PropertyBrowser.h>

#include "libzeug-version.h"

#include "Switch.h"

#ifdef WIN32
#define SETTINGS_PATH ".\\data\\propertygui.ini"
#else
#define SETTINGS_PATH "./data/propertygui.ini"
#endif

using namespace reflectionzeug;
using namespace propertyguizeug;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QApplication::setApplicationName("propertygui-example");
    QApplication::setOrganizationName(META_AUTHOR_ORGANIZATION);

    auto * widget = new QWidget();
    widget->setMinimumWidth(200);
    widget->setMaximumWidth(640);
    widget->setMinimumHeight(200);
    widget->setMaximumHeight(460);
    widget->setWindowTitle("Property Example");
    widget->setAutoFillBackground(true);

    auto * settings = new PropertyGroup("Settings");

    auto * visible = settings->addProperty<bool>("Visible",
        [widget]() {
            return widget->isVisible();
        },
        [widget](const bool & b) {
            widget->setVisible(b);
        });

    visible->setOption("tooltip", "Opens and closes the example window.");

    PropertyGroup * size = settings->addGroup("Size");

    auto * width = size->addProperty<int>("Width",
        [widget] () -> int {
            return widget->width();
        },
        [widget] (const int & width) {
            widget->resize(width, widget->height());
        });

    width->setOption("minimum", widget->minimumWidth());
    width->setOption("maximum", widget->maximumWidth());
    width->setOption("suffix", " pixel");

    auto * height = size->addProperty<int>("Height",
        [widget] () -> int {
            return widget->height();
        },
        [widget] (const int & height) {
            widget->resize(widget->width(), height);
        });

    height->setOption("minimum", widget->minimumHeight());
    height->setOption("maximum", widget->maximumHeight());
    height->setOption("suffix", " pixel");

    auto * aspect = size->addProperty<float>("Aspect",
        [widget] () -> float {
            return static_cast<float>(widget->width()) / widget->height();
        },
        [widget] (const float & aspect) {
            int width = static_cast<int>(aspect * widget->height());
            widget->resize(width, widget->height());
        });
    aspect->setOption("step", 0.1f);
    aspect->setOption("suffix", " w/h");
    aspect->setOption("precision", 4);

    const char * sizeTitles[] = { "Width", "Height" };

    auto * minimumSize = size->addProperty<std::array<int, 2>>("minimumSize",
        [widget] (size_t i) -> int {
            switch (i)
            {
            case 0:
                return widget->minimumWidth();
            case 1:
                return widget->minimumHeight();
            default:
                return -1;
            }
        },
        [widget, width, height] (size_t i, const int & size) {
            switch (i)
            {
            case 0:
                widget->setMinimumWidth(size);
                width->setOption("minimum", size);
                break;
            case 1:
                widget->setMinimumHeight(size);
                height->setOption("minimum", size);

            }
        });

    minimumSize->setOption("title", "Minimum Size");
    for (size_t i = 0; i < minimumSize->count(); ++i)
        minimumSize->at(i)->setOption("title", sizeTitles[i]);

    auto * maximumSize = size->addProperty<std::array<int, 2>>("maximumSize",
        [widget](size_t i) -> int {
            switch (i)
            {
            case 0:
                return widget->maximumWidth();
            case 1:
                return widget->maximumHeight();
            default:
                return -1;

            }
        },
        [widget, width, height] (size_t i, const int & size) {
            switch (i)
            {
            case 0:
                widget->setMaximumWidth(size);
                width->setOption("maximum", size);
                break;
            case 1:
                widget->setMaximumHeight(size);
                height->setOption("maximum", size);
            }
        });

    maximumSize->setOption("title", "Maximum Size");
    for (size_t i = 0; i < maximumSize->count(); ++i)
        maximumSize->at(i)->setOption("title", sizeTitles[i]);

    auto * windowTitle = settings->addProperty<std::string>("windowTitle",
        [widget]() {
            return widget->windowTitle().toStdString();
        },
        [widget](const std::string & title) {
            widget->setWindowTitle(QString::fromStdString(title));
        });

    windowTitle->setOption("title", "Window Title");

    auto * backgroundColor = settings->addProperty<Color>("backgroundColor",
        [widget]() {
            QColor qcolor = widget->palette().color(QPalette::Window);
            return Color(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha());
        },
        [widget](const Color & color) {
            QColor qcolor(color.red(), color.green(), color.blue(), color.alpha());
            QPalette palette;
            palette.setColor(QPalette::Window, qcolor);
            widget->setPalette(palette);
        });

    backgroundColor->setOption("title", "Background Color");
    backgroundColor->setOption("tooltip", "Sets the background color of the example window.");

    auto * cursorProperty = settings->addProperty<Qt::CursorShape>("Cursor",
        [widget] ()
        {
            return widget->cursor().shape();
        },
        [widget] (const Qt::CursorShape & shape)
        {
            widget->setCursor(QCursor(shape));
        });

    cursorProperty->setStrings({
        { Qt::PointingHandCursor, "Pointing Hand Cursor" },
        { Qt::BusyCursor, "Busy Cursor" },
        { Qt::ArrowCursor, "Arrow Cursor" },
        { Qt::WaitCursor, "Wait Cursor" }
    });

    Property<FilePath> * filePath = settings->addProperty<FilePath>("filePath", "");
    filePath->setOption("uniqueidentifier", "settings/filePath");
    filePath->setOption("tooltip", "A file path with no meaning.");

    PropertyDeserializer deserializer;
    deserializer.deserialize(*settings, SETTINGS_PATH);

    auto * browser = new PropertyBrowser(settings);
    browser->show();

    int result = a.exec();

    PropertySerializer serializer;
    serializer.serialize(*settings, SETTINGS_PATH);

    delete settings;
    delete browser;
    delete widget;

    return result;
}
<|endoftext|>


<commit_before>#include <vector>
using namespace std;
class Math{
  template <typename t> add(a, b){
    return a + b;
  }

  template <typename t> subract(a, b){
    return a - b;
  }

  template <typename t> divide(a, b){
    return a / b;
  }

  template <typename t> multiply(a, b){
    return a * b;
  }

  template <typename t> exponent(a, n){
    t value = 0;
    for(int i = 0; i < n; i++){
      value *= a;
    }
  }

 /*
 Takes in a vector of numbers and finds the mean.

 Input: A vector of numbers

 Returns: The mean of the numbers (no decimals if not floating point)
 */
 template<typename t>
 double getMean(vector <t>numbers){
	t sum = 0;
	vector<t>::iterator numberIterator
	for(vector<t>::iterator numberIterator = numbers.begin(); numberIterator < numbers.end(); numberIterator++){
	 sum += *numberIterator
	}
	return sum/numbers.size();
  }
}
<commit_msg>added variable types (Forgot)<commit_after>#include <vector>
using namespace std;
class Math{
  template <typename t> add(t a, t b){
    return a + b;
  }

  template <typename t> subract(t a, t b){
    return a - b;
  }

  template <typename t> divide(t a, t b){
    return a / b;
  }

  template <typename t> multiply(t a, t b){
    return a * b;
  }

  template <typename t> exponent(t a, t n){
    t value = 0;
    for(int i = 0; i < n; i++){
      value *= a;
    }
  }

 /*
 Takes in a vector of numbers and finds the mean.

 Input: A vector of numbers

 Returns: The mean of the numbers (no decimals if not floating point)
 */
 template<typename t>
 double getMean(vector <t>numbers){
	t sum = 0;
	vector<t>::iterator numberIterator
	for(vector<t>::iterator numberIterator = numbers.begin(); numberIterator < numbers.end(); numberIterator++){
	 sum += *numberIterator
	}
	return sum/numbers.size();
  }
}
<|endoftext|>


<commit_before>#include <lua.hpp>
#include <LuaBridge.h>
#include <RefCountedPtr.h>
#include <LuaState.h>
#include <iostream>

namespace {
void luabridge_bind(lua_State* L) {
	class Test {
	public:
		Test() {
			std::cout<<__FUNCTION__<<std::endl;
		}

		~Test() {
			std::cout<<__FUNCTION__<<std::endl;
		}
	};

	luabridge::getGlobalNamespace(L)
		.beginClass<Test>("Test")
			.addConstructor<void(*)(),RefCountedPtr<Test>>()
		.endClass()
	;
}
}

int main() {
	lua::State state;
    luabridge_bind(state.getState());
    try {
    	state.doString("Test()");
    	state.doString("blabla()");
    } catch (std::exception& e) {
    	std::cerr<<e.what()<<std::endl;
    }
}
<commit_msg>[ci skip]<commit_after>#include <lua.hpp>
#include <LuaBridge.h>
#include <RefCountedPtr.h>
#include <LuaState.h>
#include <iostream>

namespace {
void luabridge_bind(lua_State* L) {
	class Test {
	public:
		Test() {
			std::cout<<__FUNCTION__<<std::endl;
		}

		~Test() {
			std::cout<<__FUNCTION__<<std::endl;
		}
	};

	luabridge::getGlobalNamespace(L)
		.beginClass<Test>("Test")
			.addConstructor<void(*)(),RefCountedPtr<Test>>()
		.endClass()
	;
}
}

int main() {
    lua::State state;
    luabridge_bind(state.getState());
    try {
    	state.doString("Test()");
    	state.doString("blabla()");
    } catch (std::exception& e) {
    	std::cerr<<e.what()<<std::endl;
    }
}
<|endoftext|>


<commit_before>#include <string.h>
#include "utest_helper.hpp"

void test_get_arg_info(void)
{
  int ret;
  uint32_t ret_val;
  cl_kernel_arg_type_qualifier type_qual;
  size_t ret_sz;
  char name[64];

  // Setup kernel and buffers
  OCL_CREATE_KERNEL("test_get_arg_info");

  //Arg 0
  ret = clGetKernelArgInfo(kernel, 0, CL_KERNEL_ARG_ADDRESS_QUALIFIER,
                           sizeof(ret_val), &ret_val, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == sizeof(cl_kernel_arg_address_qualifier));
  OCL_ASSERT(ret_val == CL_KERNEL_ARG_ADDRESS_GLOBAL);

  ret = clGetKernelArgInfo(kernel, 0, CL_KERNEL_ARG_ACCESS_QUALIFIER,
                           sizeof(ret_val), &ret_val, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == sizeof(cl_kernel_arg_access_qualifier));
  OCL_ASSERT(ret_val == CL_KERNEL_ARG_ACCESS_NONE);

  ret = clGetKernelArgInfo(kernel, 0, CL_KERNEL_ARG_TYPE_NAME,
                           sizeof(name), name, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == strlen("float*") + 1);
  OCL_ASSERT(!strcmp(name, "float*"));

  ret = clGetKernelArgInfo(kernel, 0, CL_KERNEL_ARG_NAME,
                           sizeof(name), name, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == strlen("src") + 1);
  OCL_ASSERT(!strcmp(name, "src"));

  ret = clGetKernelArgInfo(kernel, 0, CL_KERNEL_ARG_TYPE_QUALIFIER,
                           sizeof(type_qual), &type_qual, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == sizeof(cl_kernel_arg_type_qualifier));
  OCL_ASSERT(type_qual == (CL_KERNEL_ARG_TYPE_CONST|CL_KERNEL_ARG_TYPE_VOLATILE));

  //Arg 1
  ret = clGetKernelArgInfo(kernel, 1, CL_KERNEL_ARG_ADDRESS_QUALIFIER,
                           sizeof(ret_val), &ret_val, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == sizeof(cl_kernel_arg_address_qualifier));
  OCL_ASSERT(ret_val == CL_KERNEL_ARG_ADDRESS_LOCAL);

  ret = clGetKernelArgInfo(kernel, 1, CL_KERNEL_ARG_ACCESS_QUALIFIER,
                           sizeof(ret_val), &ret_val, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == sizeof(cl_kernel_arg_access_qualifier));
  OCL_ASSERT(ret_val == CL_KERNEL_ARG_ACCESS_NONE);

  ret = clGetKernelArgInfo(kernel, 1, CL_KERNEL_ARG_TYPE_NAME,
                           sizeof(name), name, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == strlen("int*") + 1);
  OCL_ASSERT(!strcmp(name, "int*"));

  ret = clGetKernelArgInfo(kernel, 1, CL_KERNEL_ARG_NAME,
                           sizeof(name), name, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == strlen("dst") + 1);
  OCL_ASSERT(!strcmp(name, "dst"));

  ret = clGetKernelArgInfo(kernel, 1, CL_KERNEL_ARG_TYPE_QUALIFIER,
                           sizeof(type_qual), &type_qual, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == sizeof(cl_kernel_arg_type_qualifier));
  OCL_ASSERT(type_qual == CL_KERNEL_ARG_TYPE_NONE);

  //Arg 2
  ret = clGetKernelArgInfo(kernel, 2, CL_KERNEL_ARG_TYPE_NAME,
                           sizeof(name), name, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == strlen("test_arg_struct") + 1);
  OCL_ASSERT(!strcmp(name, "test_arg_struct"));
}

MAKE_UTEST_FROM_FUNCTION(test_get_arg_info);
<commit_msg>Utest: Add -cl-kernel-arg-info to the utest test_get_arg_info<commit_after>#include <string.h>
#include "utest_helper.hpp"

void test_get_arg_info(void)
{
  int ret;
  uint32_t ret_val;
  cl_kernel_arg_type_qualifier type_qual;
  size_t ret_sz;
  char name[64];

  // Setup kernel and buffers
  OCL_CALL (cl_kernel_init, "test_get_arg_info.cl", "test_get_arg_info", SOURCE, "-cl-kernel-arg-info");

  //Arg 0
  ret = clGetKernelArgInfo(kernel, 0, CL_KERNEL_ARG_ADDRESS_QUALIFIER,
                           sizeof(ret_val), &ret_val, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == sizeof(cl_kernel_arg_address_qualifier));
  OCL_ASSERT(ret_val == CL_KERNEL_ARG_ADDRESS_GLOBAL);

  ret = clGetKernelArgInfo(kernel, 0, CL_KERNEL_ARG_ACCESS_QUALIFIER,
                           sizeof(ret_val), &ret_val, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == sizeof(cl_kernel_arg_access_qualifier));
  OCL_ASSERT(ret_val == CL_KERNEL_ARG_ACCESS_NONE);

  ret = clGetKernelArgInfo(kernel, 0, CL_KERNEL_ARG_TYPE_NAME,
                           sizeof(name), name, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == strlen("float*") + 1);
  OCL_ASSERT(!strcmp(name, "float*"));

  ret = clGetKernelArgInfo(kernel, 0, CL_KERNEL_ARG_NAME,
                           sizeof(name), name, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == strlen("src") + 1);
  OCL_ASSERT(!strcmp(name, "src"));

  ret = clGetKernelArgInfo(kernel, 0, CL_KERNEL_ARG_TYPE_QUALIFIER,
                           sizeof(type_qual), &type_qual, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == sizeof(cl_kernel_arg_type_qualifier));
  OCL_ASSERT(type_qual == (CL_KERNEL_ARG_TYPE_CONST|CL_KERNEL_ARG_TYPE_VOLATILE));

  //Arg 1
  ret = clGetKernelArgInfo(kernel, 1, CL_KERNEL_ARG_ADDRESS_QUALIFIER,
                           sizeof(ret_val), &ret_val, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == sizeof(cl_kernel_arg_address_qualifier));
  OCL_ASSERT(ret_val == CL_KERNEL_ARG_ADDRESS_LOCAL);

  ret = clGetKernelArgInfo(kernel, 1, CL_KERNEL_ARG_ACCESS_QUALIFIER,
                           sizeof(ret_val), &ret_val, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == sizeof(cl_kernel_arg_access_qualifier));
  OCL_ASSERT(ret_val == CL_KERNEL_ARG_ACCESS_NONE);

  ret = clGetKernelArgInfo(kernel, 1, CL_KERNEL_ARG_TYPE_NAME,
                           sizeof(name), name, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == strlen("int*") + 1);
  OCL_ASSERT(!strcmp(name, "int*"));

  ret = clGetKernelArgInfo(kernel, 1, CL_KERNEL_ARG_NAME,
                           sizeof(name), name, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == strlen("dst") + 1);
  OCL_ASSERT(!strcmp(name, "dst"));

  ret = clGetKernelArgInfo(kernel, 1, CL_KERNEL_ARG_TYPE_QUALIFIER,
                           sizeof(type_qual), &type_qual, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == sizeof(cl_kernel_arg_type_qualifier));
  OCL_ASSERT(type_qual == CL_KERNEL_ARG_TYPE_NONE);

  //Arg 2
  ret = clGetKernelArgInfo(kernel, 2, CL_KERNEL_ARG_TYPE_NAME,
                           sizeof(name), name, &ret_sz);
  OCL_ASSERT(ret == CL_SUCCESS);
  OCL_ASSERT(ret_sz == strlen("test_arg_struct") + 1);
  OCL_ASSERT(!strcmp(name, "test_arg_struct"));
}

MAKE_UTEST_FROM_FUNCTION(test_get_arg_info);
<|endoftext|>


<commit_before>#ifndef MAIN_FRAME_H
#define MAIN_FRAME_H

//(*Headers(MainFrame)
#include <wx/listctrl.h>
#include <wx/menu.h>
#include <wx/panel.h>
#include <wx/button.h>
#include <wx/frame.h>
#include <wx/statusbr.h>
//*)

#include "../Partmod/disk.h"
#include "../Partmod/disk_exception.h"

#define S_PARTITION    1
#define S_FREE_SPACE   2

struct sel_type
{
  int      type;
  uint32_t flags;
};

struct lvlist
{
std::string partition,
            type,
            fs_type,
            size,
            free,
            begin_sect,
            last_sect,
            mountpoint;

int num;

int      selection_type;
uint32_t flags;

};

class MainFrame: public wxFrame
{
	public:

		MainFrame(wxWindow* parent,wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize);
		virtual ~MainFrame();

		//(*Declarations(MainFrame)
		wxMenuItem* MenuOpenDiskImage;
		wxMenuItem* MenuAbout;
		wxListView* partitionList;
		wxListView* diskList;
		wxMenu* menuPartition;
		wxMenuItem* MenuRestoreBackup;
		wxMenuItem* MenuSaveChanges;
		wxMenu* menuActions;
		wxMenuItem* MenuSetInactive;
		wxButton* Button1;
		wxMenuItem* MenuListGuid;
		wxMenuItem* MenuDeletePartition;
		wxPanel* Panel1;
		wxMenuItem* MenuCloseDisk;
		wxMenuItem* MenuPartitionProperties;
		wxButton* Button2;
		wxMenuItem* MenuSetActive;
		wxMenu* menuHelp;
		wxMenuItem* MenuCreateBackup;
		wxStatusBar* StatusBar1;
		wxMenu* menuTools;
		wxMenu* menuDisk;
		wxMenuItem* MenuWipePartition;
		wxMenuItem* MenuCreatePartition;
		wxMenuItem* MenuQuit;
		wxMenuBar* menuBar;
		//*)

	protected:

		//(*Identifiers(MainFrame)
		static const long ID_LISTVIEW1;
		static const long ID_LISTVIEW2;
		static const long ID_BUTTON1;
		static const long ID_BUTTON2;
		static const long ID_PANEL1;
		static const long ID_SAVE_CHANGES;
		static const long ID_QUIT;
		static const long ID_CLOSE_DISK;
		static const long ID_OPEN_DISK_IMAGE;
		static const long ID_CREATE_BACKUP;
		static const long ID_RESTORE_BACKUP;
		static const long ID_CREATE_PARTITION;
		static const long ID_DELETE_PARTITION;
		static const long ID_SET_ACTIVE;
		static const long ID_SET_INACTIVE;
		static const long ID_PARTITION_PROPERTIES;
		static const long ID_WIPE_PARTITION;
		static const long ID_LIST_GUID;
		static const long ID_ABOUT;
		static const long ID_STATUSBAR1;
		//*)

	private:
	    Disk *disk;
        std::vector<lvlist> disk_structure; // list of partition and free space slices
        int selected_partition,selected_frs;

		//(*Handlers(MainFrame)
		void OndiskListItemActivated(wxListEvent& event);
		void OnMenuCloseDiskSelected(wxCommandEvent& event);
		void OnMenuSaveChangesSelected(wxCommandEvent& event);
		void OnMenuQuitSelected(wxCommandEvent& event);
		void OnMenuOpenDiskImageSelected(wxCommandEvent& event);
		void OnMenuCreateBackupSelected(wxCommandEvent& event);
		void OnMenuRestoreBackupSelected(wxCommandEvent& event);
		void OnMenuCreatePartitionSelected(wxCommandEvent& event);
		void OnMenuDeletePartitionSelected(wxCommandEvent& event);
		void OnMenuSetActiveSelected(wxCommandEvent& event);
		void OnMenuSetInactiveSelected(wxCommandEvent& event);
		void OnMenuWipePartitionSelected(wxCommandEvent& event);
		void OnMenuListGuidSelected(wxCommandEvent& event);
		void OnMenuAboutSelected(wxCommandEvent& event);
		void OnPartitionListItemActivated(wxListEvent& event);
		void OnPartitionListItemRClick(wxListEvent& event);
		void OnMenuPartitionPropertiesSelected(wxCommandEvent& event);
		void OnPartitionListItemDeselect(wxListEvent& event);
		//*)
        void OnPartitionListPopupClick(wxListEvent& event);

        void refresh_disk_list();
        void refresh_partition_list();

		DECLARE_EVENT_TABLE()
};

#endif
<commit_msg>git-svn-id: svn://svn.code.sf.net/p/partmodproject/code/trunk@23 3d63fe75-a90b-4577-b595-b0b07fb0d485<commit_after>#ifndef MAIN_FRAME_H
#define MAIN_FRAME_H

//(*Headers(MainFrame)
#include <wx/listctrl.h>
#include <wx/menu.h>
#include <wx/panel.h>
#include <wx/button.h>
#include <wx/frame.h>
#include <wx/statusbr.h>
//*)

#include "../Partmod/disk.h"
#include "../Partmod/disk_exception.h"

#define S_PARTITION    1
#define S_FREE_SPACE   2

struct lvlist
{
std::string partition,
            type,
            fs_type,
            size,
            free,
            begin_sect,
            last_sect,
            mountpoint;

int num;

int      selection_type;
uint32_t flags;

};

class MainFrame: public wxFrame
{
	public:

		MainFrame(wxWindow* parent,wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize);
		virtual ~MainFrame();

		//(*Declarations(MainFrame)
		wxMenuItem* MenuOpenDiskImage;
		wxMenuItem* MenuAbout;
		wxListView* partitionList;
		wxListView* diskList;
		wxMenu* menuPartition;
		wxMenuItem* MenuRestoreBackup;
		wxMenuItem* MenuSaveChanges;
		wxMenu* menuActions;
		wxMenuItem* MenuSetInactive;
		wxMenuItem* MenuListGuid;
		wxMenuItem* MenuDeletePartition;
		wxPanel* Panel1;
		wxMenuItem* MenuCloseDisk;
		wxMenuItem* MenuPartitionProperties;
		wxMenuItem* MenuSetActive;
		wxButton* ButtonSaveChanges;
		wxMenu* menuHelp;
		wxMenuItem* MenuCreateBackup;
		wxStatusBar* StatusBar1;
		wxMenu* menuTools;
		wxButton* ButtonQuit;
		wxMenu* menuDisk;
		wxMenuItem* MenuWipePartition;
		wxMenuItem* MenuCreatePartition;
		wxMenuItem* MenuQuit;
		wxMenuBar* menuBar;
		//*)

	protected:

		//(*Identifiers(MainFrame)
		static const long ID_LISTVIEW1;
		static const long ID_LISTVIEW2;
		static const long ID_BUTTON1;
		static const long ID_BUTTON2;
		static const long ID_PANEL1;
		static const long ID_SAVE_CHANGES;
		static const long ID_QUIT;
		static const long ID_CLOSE_DISK;
		static const long ID_OPEN_DISK_IMAGE;
		static const long ID_CREATE_BACKUP;
		static const long ID_RESTORE_BACKUP;
		static const long ID_CREATE_PARTITION;
		static const long ID_DELETE_PARTITION;
		static const long ID_SET_ACTIVE;
		static const long ID_SET_INACTIVE;
		static const long ID_PARTITION_PROPERTIES;
		static const long ID_WIPE_PARTITION;
		static const long ID_LIST_GUID;
		static const long ID_ABOUT;
		static const long ID_STATUSBAR1;
		//*)

	private:
	    Disk *disk;
        std::vector<lvlist> disk_structure; // list of partition and free space slices
        int selected_partition,selected_frs;

		//(*Handlers(MainFrame)
		void OndiskListItemActivated(wxListEvent& event);
		void OnMenuCloseDiskSelected(wxCommandEvent& event);
		void OnMenuSaveChangesSelected(wxCommandEvent& event);
		void OnMenuQuitSelected(wxCommandEvent& event);
		void OnMenuOpenDiskImageSelected(wxCommandEvent& event);
		void OnMenuCreateBackupSelected(wxCommandEvent& event);
		void OnMenuRestoreBackupSelected(wxCommandEvent& event);
		void OnMenuCreatePartitionSelected(wxCommandEvent& event);
		void OnMenuDeletePartitionSelected(wxCommandEvent& event);
		void OnMenuSetActiveSelected(wxCommandEvent& event);
		void OnMenuSetInactiveSelected(wxCommandEvent& event);
		void OnMenuWipePartitionSelected(wxCommandEvent& event);
		void OnMenuListGuidSelected(wxCommandEvent& event);
		void OnMenuAboutSelected(wxCommandEvent& event);
		void OnPartitionListItemActivated(wxListEvent& event);
		void OnPartitionListItemRClick(wxListEvent& event);
		void OnMenuPartitionPropertiesSelected(wxCommandEvent& event);
		void OnPartitionListItemDeselect(wxListEvent& event);
		//*)
        void OnPartitionListPopupClick(wxListEvent& event);

        void refresh_disk_list();
        void refresh_partition_list();

		DECLARE_EVENT_TABLE()
};

#endif
<|endoftext|>


<commit_before><commit_msg>Fix build errors with latest ibus<commit_after><|endoftext|>


<commit_before>/*
 * ZoteroCollections.cpp
 *
 * Copyright (C) 2009-20 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "ZoteroCollections.hpp"

#include <shared_core/Error.hpp>
#include <shared_core/json/Json.hpp>

#include <core/Hash.hpp>

#include <core/FileSerializer.hpp>

#include <session/prefs/UserState.hpp>
#include <session/prefs/UserPrefs.hpp>
#include <session/SessionModuleContext.hpp>
#include <session/projects/SessionProjects.hpp>
#include <session/SessionAsyncDownloadFile.hpp>

#include "ZoteroCollectionsLocal.hpp"
#include "ZoteroCollectionsWeb.hpp"
#include "ZoteroUtil.hpp"

using namespace rstudio::core;

namespace rstudio {
namespace session {
namespace modules {
namespace zotero {
namespace collections {

namespace {

const char * const kIndexFile = "INDEX";
const char * const kFile = "file";

FilePath collectionsCacheDir(const std::string& type, const std::string& context)
{
   // cache dir name (depends on whether bbt is enabled as when that changes it should invalidate all cache entries)
   std::string dirName = "libraries";
   if (session::prefs::userState().zoteroUseBetterBibtex())
      dirName += "-bbt";

   // ~/.local/share/rstudio/zotero/libraries
   FilePath cachePath = module_context::userScratchPath()
      .completeChildPath("zotero")
      .completeChildPath(dirName)
      .completeChildPath(type)
      .completeChildPath(context);
   Error error = cachePath.ensureDirectory();
   if (error)
      LOG_ERROR(error);
   return cachePath;
}

struct IndexedCollection
{
   bool empty() const { return file.empty(); }
   int version;
   std::string file;
   std::string key;
   std::string parentKey;
};

std::map<std::string,IndexedCollection> collectionsCacheIndex(const FilePath& cacheDir)
{
   std::map<std::string,IndexedCollection> index;

   FilePath indexFile = cacheDir.completeChildPath(kIndexFile);
   if (indexFile.exists())
   {
      std::string indexContents;
      Error error = core::readStringFromFile(indexFile, &indexContents);
      if (!error)
      {
         json::Object indexJson;
         error = indexJson.parse(indexContents);
         if (!error)
         {
            std::for_each(indexJson.begin(), indexJson.end(), [&index](json::Object::Member member) {

               json::Object entryJson = member.getValue().getObject();
               IndexedCollection coll;
               coll.version = entryJson[kVersion].getInt();
               coll.file = entryJson[kFile].getString();
               coll.key = entryJson[kKey].getString();
               coll.parentKey = entryJson[kParentKey].getString();
               index.insert(std::make_pair(member.getName(),coll));
            });
         }
      }

      if (error)
         LOG_ERROR(error);
   }

   return index;
}

void updateCollectionsCacheIndex(const FilePath& cacheDir, const std::map<std::string,IndexedCollection>& index)
{
   // create json for index
   json::Object indexJson;
   for (auto item : index)
   {
      json::Object collJson;
      collJson[kVersion] = item.second.version;
      collJson[kFile] = item.second.file;
      collJson[kKey] = item.second.key;
      collJson[kParentKey] = item.second.parentKey;
      indexJson[item.first] = collJson;
   }

   // write index
   FilePath indexFile = cacheDir.completeChildPath(kIndexFile);
   Error error = core::writeStringToFile(indexFile, indexJson.writeFormatted());
   if (error)
      LOG_ERROR(error);
}

Error readCollection(const FilePath& filePath, ZoteroCollection* pCollection)
{
   std::string cacheContents;
   Error error = core::readStringFromFile(filePath, &cacheContents);
   if (error)
      return error;

   json::Object collectionJson;
   error = collectionJson.parse(cacheContents);
   if (error)
      return error;

   pCollection->name = collectionJson[kName].getString();
   pCollection->version = collectionJson[kVersion].getInt();
   pCollection->key = collectionJson[kKey].getString();
   pCollection->parentKey = collectionJson[kParentKey].getString();
   pCollection->items = collectionJson[kItems].getArray();

   return Success();
}

ZoteroCollection cachedCollection(const std::string& type, const std::string& context, const std::string& name)
{
   ZoteroCollection collection;
   FilePath cacheDir = collectionsCacheDir(type, context);
   auto index = collectionsCacheIndex(cacheDir);
   auto coll = index[name];
   if (!coll.empty())
   {
      FilePath cachePath = cacheDir.completeChildPath(coll.file);
      Error error = readCollection(cachePath, &collection);
      if (error)
         LOG_ERROR(error);
   }
   return collection;
}

ZoteroCollectionSpec cachedCollectionSpec(const std::string& type, const std::string& context, const std::string& name)
{
   ZoteroCollectionSpec spec;
   FilePath cacheDir = collectionsCacheDir(type, context);
   auto index = collectionsCacheIndex(cacheDir);
   auto coll = index[name];
   if (!coll.empty())
   {
      spec.name = name;
      spec.version = coll.version;
   }
   return spec;
}

ZoteroCollectionSpecs cachedCollectionsSpecs(const std::string& type, const std::string& context)
{
   ZoteroCollectionSpecs specs;
   FilePath cacheDir = collectionsCacheDir(type, context);
   auto index = collectionsCacheIndex(cacheDir);
   for (auto entry : index)
   {
      ZoteroCollectionSpec spec(entry.first, entry.second.key, entry.second.parentKey, entry.second.version);
      specs.push_back(spec);
   }
   return specs;
}

void updateCachedCollection(const std::string& type, const std::string& context, const std::string& name, const ZoteroCollection& collection)
{
   // update index
   FilePath cacheDir = collectionsCacheDir(type, context);
   auto index = collectionsCacheIndex(cacheDir);
   auto coll = index[name];
   if (coll.empty())
      coll.file = core::system::generateShortenedUuid();
   coll.version = collection.version;
   index[name] = coll;
   updateCollectionsCacheIndex(cacheDir, index);

   // write the collection
   json::Object collectionJson;
   collectionJson[kName] = collection.name;
   collectionJson[kVersion] = collection.version;
   collectionJson[kKey] = collection.key;
   collectionJson[kParentKey] = collection.parentKey;
   collectionJson[kItems] = collection.items;
   Error error = core::writeStringToFile(cacheDir.completeChildPath(coll.file), collectionJson.writeFormatted());
   if (error)
      LOG_ERROR(error);
}

// repsond with either a collection from the server cache or just name/version if the client
// already has the same version
ZoteroCollection responseFromServerCache(const std::string& type,
                                         const std::string& apiKey,
                                         const std::string& collection,
                                         const ZoteroCollectionSpecs& clientCacheSpecs)
{
   ZoteroCollection cached = cachedCollection(type, apiKey, collection);
   if (!cached.empty() )
   {
      // see if the client specs already indicate an up to date version
      ZoteroCollectionSpecs::const_iterator clientIt = std::find_if(clientCacheSpecs.begin(), clientCacheSpecs.end(), [cached](ZoteroCollectionSpec spec) {
         return spec.name == cached.name && spec.version == cached.version;
      });
      if (clientIt == clientCacheSpecs.end())
      {
         // client spec didn't match, return cached collection
         TRACE("Returning server cache for " + collection, cached.items.getSize());
         return cached;
      }
      else
      {
         // client had up to date version, just return the spec w/ no items
         TRACE("Using client cache for " + collection);
         return ZoteroCollection(*clientIt);
      }
   }
   else
   {
      return ZoteroCollection();
   }

}

struct Connection
{
   bool empty() const { return type.length() == 0; }
   std::string type;
   std::string context;
   std::string cacheContext;
   ZoteroCollectionSource source;
};

Connection zoteroConnection()
{
   // use local connection if available for 'auto'
   std::string type = prefs::userState().zoteroConnectionType();
   if ((type.empty() || type == kZoteroConnectionTypeAuto) && localZoteroAvailable())
       type = kZoteroConnectionTypeLocal;

   // return empty connection if it's none or auto (as auto would have already been resolved)
   if (type == kZoteroConnectionTypeAuto || type == kZoteroConnectionTypeNone)
   {
      return Connection();
   }

   // initialize context
   std::string context;
   if (type == kZoteroConnectionTypeLocal)
   {
      FilePath localDataDir = zoteroDataDirectory();
      if (!localDataDir.isEmpty())
      {
         if (localDataDir.exists())
            context = localDataDir.getAbsolutePath();
         else
            LOG_ERROR(core::fileNotFoundError(localDataDir, ERROR_LOCATION));
      }
   }
   else
   {
      context = prefs::userState().zoteroApiKey();
   }

   // if we have a context then proceed to fill out the connection, otherwise
   // just return an empty connection. we wouldn't have a context if we were
   // configured for a local connection (the default) but there was no zotero
   // data directory. we also woudln't have a context if we were configured
   // for a web connection and there was no zotero API key
   if (!context.empty())
   {
      Connection connection;
      connection.type = type;
      connection.context = context;
      // use a hash of the context for the cacheContext (as it might not be a valid directory name)
      connection.cacheContext = core::hash::crc32HexHash(context);
      connection.source = type == kZoteroConnectionTypeLocal ? collections::localCollections() : collections::webCollections();
      return connection;
   }
   else
   {
      return Connection();
   }
}

} // end anonymous namespace

const char * const kName = "name";
const char * const kVersion = "version";
const char * const kKey = "key";
const char * const kParentKey = "parentKey";
const char * const kItems = "items";

const int kNoVersion = -1;

ZoteroCollectionSpec findParentSpec(const ZoteroCollectionSpec& spec, const ZoteroCollectionSpecs& specs)
{
   // search for parentKey if we have one
   if (!spec.parentKey.empty())
   {
      auto it = std::find_if(specs.begin(), specs.end(), [spec](const ZoteroCollectionSpec& s) { return s.key == spec.parentKey; });
      if (it != specs.end())
         return *it;
   }

   // not found
   return ZoteroCollectionSpec();
}

void getCollectionSpecs(std::vector<std::string> collections, ZoteroCollectionSpecsHandler handler)
{
   // get connection if we have one
   Connection conn = zoteroConnection();
   if (!conn.empty())
   {
      conn.source.getCollectionSpecs(conn.context, collections, handler);
   }
   else
   {
      handler(Success(), std::vector<ZoteroCollectionSpec>());
   }
}

void getLibraryNames(ZoteroLibrariesHandler handler)
{
   // get connection if we have one
   Connection conn = zoteroConnection();
   if (!conn.empty())
   {
      conn.source.getLibraryNames(conn.context, handler);
   }
   else
   {
      handler(Success(), std::vector<std::string>());
   }
}

void getCollections(std::vector<std::string> collections,
                    ZoteroCollectionSpecs cacheSpecs,
                    bool useCache,
                    ZoteroCollectionsHandler handler)
{
   // clear out client cache specs if the cache is disabled
   if (!useCache)
      cacheSpecs.clear();

   // get connection if we have o ne
   Connection conn = zoteroConnection();
   if (!conn.empty())
   {
      // create a set of specs based on what we have in our server cache (as we always want to keep our cache up to date)
      ZoteroCollectionSpecs serverCacheSpecs;
      if (useCache)
      {
         // request for explicit list of collections, provide specs for matching collections from the server cache
         if (!collections.empty())
         {
            std::transform(collections.begin(), collections.end(), std::back_inserter(serverCacheSpecs), [conn](std::string name) {
               ZoteroCollectionSpec cacheSpec(name);
               ZoteroCollectionSpec cached = cachedCollectionSpec(conn.type, conn.cacheContext, name);
               if (!cached.empty())
                  cacheSpec.version = cached.version;
               return cacheSpec;
            });
         }

         // request for all collections, provide specs for all collections in the server cache
         else
         {
            serverCacheSpecs = cachedCollectionsSpecs(conn.type, conn.cacheContext);
         }
      }

      // get collections
      conn.source.getCollections(conn.context, collections, serverCacheSpecs,
                                 [conn, collections, cacheSpecs, serverCacheSpecs, handler](Error error, ZoteroCollections webCollections, std::string warning) {

         // process response -- for any collection returned w/ a version higher than that in the
         // cache, update the cache. for any collection available (from cache or web) with a version
         // higher than that of the client request, return the updated items (else return no items)
         if (!error)
         {
            ZoteroCollections responseCollections;
            for (auto webCollection : webCollections)
            {
               // see if the server side cache needs updating
               ZoteroCollectionSpecs::const_iterator it = std::find_if(serverCacheSpecs.begin(), serverCacheSpecs.end(), [webCollection](ZoteroCollectionSpec cacheSpec) {
                  return cacheSpec.name == webCollection.name && cacheSpec.version == webCollection.version;
               });
               // need to update the cache -- do so and then return the just cached copy to the client
               if (it == serverCacheSpecs.end())
               {
                  TRACE("Updating server cache for " + webCollection.name);
                  updateCachedCollection(conn.type, conn.cacheContext, webCollection.name, webCollection);
                  TRACE("Returning server cache for " + webCollection.name);
                  responseCollections.push_back(webCollection);
               }

               // we have a cache for this collection, check to see if it is recent enough (and in that
               // case don't return the items to the client)
               else
               {
                  // see we can satisfy the request from our cache
                  ZoteroCollection cached = responseFromServerCache(conn.type, conn.cacheContext, webCollection.name, cacheSpecs);
                  if (!cached.empty())
                  {
                     responseCollections.push_back(cached);
                  }
                  else
                  {
                     // shouldn't be possible to get here (as the initial condition tested in the loop ensures
                     // that we have a cached collection)
                     TRACE("Unexpected failure to find cache for " + webCollection.name);
                  }
               }
            }

            handler(Success(), responseCollections, warning);

         // for host errors try to serve from the cache
         } else if (isHostError(core::errorDescription(error))) {

            ZoteroCollections responseCollections;
            for (auto collection : collections)
            {
               ZoteroCollection cached = responseFromServerCache(conn.type, conn.cacheContext, collection, cacheSpecs);
               if (!cached.empty())
                  responseCollections.push_back(cached);
            }
            handler(Success(),responseCollections, warning);

         // report error
         } else {
            handler(error, std::vector<ZoteroCollection>(), warning);
         }

      });
   }
   else
   {
      handler(Success(), std::vector<ZoteroCollection>(), "");
   }

}

} // end namespace collections
} // end namespace zotero
} // end namespace modules
} // end namespace session
} // end namespace rstudio
<commit_msg>rename zotero cache dir<commit_after>/*
 * ZoteroCollections.cpp
 *
 * Copyright (C) 2009-20 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "ZoteroCollections.hpp"

#include <shared_core/Error.hpp>
#include <shared_core/json/Json.hpp>

#include <core/Hash.hpp>

#include <core/FileSerializer.hpp>

#include <session/prefs/UserState.hpp>
#include <session/prefs/UserPrefs.hpp>
#include <session/SessionModuleContext.hpp>
#include <session/projects/SessionProjects.hpp>
#include <session/SessionAsyncDownloadFile.hpp>

#include "ZoteroCollectionsLocal.hpp"
#include "ZoteroCollectionsWeb.hpp"
#include "ZoteroUtil.hpp"

using namespace rstudio::core;

namespace rstudio {
namespace session {
namespace modules {
namespace zotero {
namespace collections {

namespace {

const char * const kIndexFile = "INDEX";
const char * const kFile = "file";

FilePath collectionsCacheDir(const std::string& type, const std::string& context)
{
   // cache dir name (depends on whether bbt is enabled as when that changes it should invalidate all cache entries)
   std::string dirName = "libraries-cache";
   if (session::prefs::userState().zoteroUseBetterBibtex())
      dirName += "-bbt";

   // ~/.local/share/rstudio/zotero/libraries
   FilePath cachePath = module_context::userScratchPath()
      .completeChildPath("zotero")
      .completeChildPath(dirName)
      .completeChildPath(type)
      .completeChildPath(context);
   Error error = cachePath.ensureDirectory();
   if (error)
      LOG_ERROR(error);
   return cachePath;
}

struct IndexedCollection
{
   bool empty() const { return file.empty(); }
   int version;
   std::string file;
   std::string key;
   std::string parentKey;
};

std::map<std::string,IndexedCollection> collectionsCacheIndex(const FilePath& cacheDir)
{
   std::map<std::string,IndexedCollection> index;

   FilePath indexFile = cacheDir.completeChildPath(kIndexFile);
   if (indexFile.exists())
   {
      std::string indexContents;
      Error error = core::readStringFromFile(indexFile, &indexContents);
      if (!error)
      {
         json::Object indexJson;
         error = indexJson.parse(indexContents);
         if (!error)
         {
            std::for_each(indexJson.begin(), indexJson.end(), [&index](json::Object::Member member) {

               json::Object entryJson = member.getValue().getObject();
               IndexedCollection coll;
               coll.version = entryJson[kVersion].getInt();
               coll.file = entryJson[kFile].getString();
               coll.key = entryJson[kKey].getString();
               coll.parentKey = entryJson[kParentKey].getString();
               index.insert(std::make_pair(member.getName(),coll));
            });
         }
      }

      if (error)
         LOG_ERROR(error);
   }

   return index;
}

void updateCollectionsCacheIndex(const FilePath& cacheDir, const std::map<std::string,IndexedCollection>& index)
{
   // create json for index
   json::Object indexJson;
   for (auto item : index)
   {
      json::Object collJson;
      collJson[kVersion] = item.second.version;
      collJson[kFile] = item.second.file;
      collJson[kKey] = item.second.key;
      collJson[kParentKey] = item.second.parentKey;
      indexJson[item.first] = collJson;
   }

   // write index
   FilePath indexFile = cacheDir.completeChildPath(kIndexFile);
   Error error = core::writeStringToFile(indexFile, indexJson.writeFormatted());
   if (error)
      LOG_ERROR(error);
}

Error readCollection(const FilePath& filePath, ZoteroCollection* pCollection)
{
   std::string cacheContents;
   Error error = core::readStringFromFile(filePath, &cacheContents);
   if (error)
      return error;

   json::Object collectionJson;
   error = collectionJson.parse(cacheContents);
   if (error)
      return error;

   pCollection->name = collectionJson[kName].getString();
   pCollection->version = collectionJson[kVersion].getInt();
   pCollection->key = collectionJson[kKey].getString();
   pCollection->parentKey = collectionJson[kParentKey].getString();
   pCollection->items = collectionJson[kItems].getArray();

   return Success();
}

ZoteroCollection cachedCollection(const std::string& type, const std::string& context, const std::string& name)
{
   ZoteroCollection collection;
   FilePath cacheDir = collectionsCacheDir(type, context);
   auto index = collectionsCacheIndex(cacheDir);
   auto coll = index[name];
   if (!coll.empty())
   {
      FilePath cachePath = cacheDir.completeChildPath(coll.file);
      Error error = readCollection(cachePath, &collection);
      if (error)
         LOG_ERROR(error);
   }
   return collection;
}

ZoteroCollectionSpec cachedCollectionSpec(const std::string& type, const std::string& context, const std::string& name)
{
   ZoteroCollectionSpec spec;
   FilePath cacheDir = collectionsCacheDir(type, context);
   auto index = collectionsCacheIndex(cacheDir);
   auto coll = index[name];
   if (!coll.empty())
   {
      spec.name = name;
      spec.version = coll.version;
   }
   return spec;
}

ZoteroCollectionSpecs cachedCollectionsSpecs(const std::string& type, const std::string& context)
{
   ZoteroCollectionSpecs specs;
   FilePath cacheDir = collectionsCacheDir(type, context);
   auto index = collectionsCacheIndex(cacheDir);
   for (auto entry : index)
   {
      ZoteroCollectionSpec spec(entry.first, entry.second.key, entry.second.parentKey, entry.second.version);
      specs.push_back(spec);
   }
   return specs;
}

void updateCachedCollection(const std::string& type, const std::string& context, const std::string& name, const ZoteroCollection& collection)
{
   // update index
   FilePath cacheDir = collectionsCacheDir(type, context);
   auto index = collectionsCacheIndex(cacheDir);
   auto coll = index[name];
   if (coll.empty())
      coll.file = core::system::generateShortenedUuid();
   coll.version = collection.version;
   index[name] = coll;
   updateCollectionsCacheIndex(cacheDir, index);

   // write the collection
   json::Object collectionJson;
   collectionJson[kName] = collection.name;
   collectionJson[kVersion] = collection.version;
   collectionJson[kKey] = collection.key;
   collectionJson[kParentKey] = collection.parentKey;
   collectionJson[kItems] = collection.items;
   Error error = core::writeStringToFile(cacheDir.completeChildPath(coll.file), collectionJson.writeFormatted());
   if (error)
      LOG_ERROR(error);
}

// repsond with either a collection from the server cache or just name/version if the client
// already has the same version
ZoteroCollection responseFromServerCache(const std::string& type,
                                         const std::string& apiKey,
                                         const std::string& collection,
                                         const ZoteroCollectionSpecs& clientCacheSpecs)
{
   ZoteroCollection cached = cachedCollection(type, apiKey, collection);
   if (!cached.empty() )
   {
      // see if the client specs already indicate an up to date version
      ZoteroCollectionSpecs::const_iterator clientIt = std::find_if(clientCacheSpecs.begin(), clientCacheSpecs.end(), [cached](ZoteroCollectionSpec spec) {
         return spec.name == cached.name && spec.version == cached.version;
      });
      if (clientIt == clientCacheSpecs.end())
      {
         // client spec didn't match, return cached collection
         TRACE("Returning server cache for " + collection, cached.items.getSize());
         return cached;
      }
      else
      {
         // client had up to date version, just return the spec w/ no items
         TRACE("Using client cache for " + collection);
         return ZoteroCollection(*clientIt);
      }
   }
   else
   {
      return ZoteroCollection();
   }

}

struct Connection
{
   bool empty() const { return type.length() == 0; }
   std::string type;
   std::string context;
   std::string cacheContext;
   ZoteroCollectionSource source;
};

Connection zoteroConnection()
{
   // use local connection if available for 'auto'
   std::string type = prefs::userState().zoteroConnectionType();
   if ((type.empty() || type == kZoteroConnectionTypeAuto) && localZoteroAvailable())
       type = kZoteroConnectionTypeLocal;

   // return empty connection if it's none or auto (as auto would have already been resolved)
   if (type == kZoteroConnectionTypeAuto || type == kZoteroConnectionTypeNone)
   {
      return Connection();
   }

   // initialize context
   std::string context;
   if (type == kZoteroConnectionTypeLocal)
   {
      FilePath localDataDir = zoteroDataDirectory();
      if (!localDataDir.isEmpty())
      {
         if (localDataDir.exists())
            context = localDataDir.getAbsolutePath();
         else
            LOG_ERROR(core::fileNotFoundError(localDataDir, ERROR_LOCATION));
      }
   }
   else
   {
      context = prefs::userState().zoteroApiKey();
   }

   // if we have a context then proceed to fill out the connection, otherwise
   // just return an empty connection. we wouldn't have a context if we were
   // configured for a local connection (the default) but there was no zotero
   // data directory. we also woudln't have a context if we were configured
   // for a web connection and there was no zotero API key
   if (!context.empty())
   {
      Connection connection;
      connection.type = type;
      connection.context = context;
      // use a hash of the context for the cacheContext (as it might not be a valid directory name)
      connection.cacheContext = core::hash::crc32HexHash(context);
      connection.source = type == kZoteroConnectionTypeLocal ? collections::localCollections() : collections::webCollections();
      return connection;
   }
   else
   {
      return Connection();
   }
}

} // end anonymous namespace

const char * const kName = "name";
const char * const kVersion = "version";
const char * const kKey = "key";
const char * const kParentKey = "parentKey";
const char * const kItems = "items";

const int kNoVersion = -1;

ZoteroCollectionSpec findParentSpec(const ZoteroCollectionSpec& spec, const ZoteroCollectionSpecs& specs)
{
   // search for parentKey if we have one
   if (!spec.parentKey.empty())
   {
      auto it = std::find_if(specs.begin(), specs.end(), [spec](const ZoteroCollectionSpec& s) { return s.key == spec.parentKey; });
      if (it != specs.end())
         return *it;
   }

   // not found
   return ZoteroCollectionSpec();
}

void getCollectionSpecs(std::vector<std::string> collections, ZoteroCollectionSpecsHandler handler)
{
   // get connection if we have one
   Connection conn = zoteroConnection();
   if (!conn.empty())
   {
      conn.source.getCollectionSpecs(conn.context, collections, handler);
   }
   else
   {
      handler(Success(), std::vector<ZoteroCollectionSpec>());
   }
}

void getLibraryNames(ZoteroLibrariesHandler handler)
{
   // get connection if we have one
   Connection conn = zoteroConnection();
   if (!conn.empty())
   {
      conn.source.getLibraryNames(conn.context, handler);
   }
   else
   {
      handler(Success(), std::vector<std::string>());
   }
}

void getCollections(std::vector<std::string> collections,
                    ZoteroCollectionSpecs cacheSpecs,
                    bool useCache,
                    ZoteroCollectionsHandler handler)
{
   // clear out client cache specs if the cache is disabled
   if (!useCache)
      cacheSpecs.clear();

   // get connection if we have o ne
   Connection conn = zoteroConnection();
   if (!conn.empty())
   {
      // create a set of specs based on what we have in our server cache (as we always want to keep our cache up to date)
      ZoteroCollectionSpecs serverCacheSpecs;
      if (useCache)
      {
         // request for explicit list of collections, provide specs for matching collections from the server cache
         if (!collections.empty())
         {
            std::transform(collections.begin(), collections.end(), std::back_inserter(serverCacheSpecs), [conn](std::string name) {
               ZoteroCollectionSpec cacheSpec(name);
               ZoteroCollectionSpec cached = cachedCollectionSpec(conn.type, conn.cacheContext, name);
               if (!cached.empty())
                  cacheSpec.version = cached.version;
               return cacheSpec;
            });
         }

         // request for all collections, provide specs for all collections in the server cache
         else
         {
            serverCacheSpecs = cachedCollectionsSpecs(conn.type, conn.cacheContext);
         }
      }

      // get collections
      conn.source.getCollections(conn.context, collections, serverCacheSpecs,
                                 [conn, collections, cacheSpecs, serverCacheSpecs, handler](Error error, ZoteroCollections webCollections, std::string warning) {

         // process response -- for any collection returned w/ a version higher than that in the
         // cache, update the cache. for any collection available (from cache or web) with a version
         // higher than that of the client request, return the updated items (else return no items)
         if (!error)
         {
            ZoteroCollections responseCollections;
            for (auto webCollection : webCollections)
            {
               // see if the server side cache needs updating
               ZoteroCollectionSpecs::const_iterator it = std::find_if(serverCacheSpecs.begin(), serverCacheSpecs.end(), [webCollection](ZoteroCollectionSpec cacheSpec) {
                  return cacheSpec.name == webCollection.name && cacheSpec.version == webCollection.version;
               });
               // need to update the cache -- do so and then return the just cached copy to the client
               if (it == serverCacheSpecs.end())
               {
                  TRACE("Updating server cache for " + webCollection.name);
                  updateCachedCollection(conn.type, conn.cacheContext, webCollection.name, webCollection);
                  TRACE("Returning server cache for " + webCollection.name);
                  responseCollections.push_back(webCollection);
               }

               // we have a cache for this collection, check to see if it is recent enough (and in that
               // case don't return the items to the client)
               else
               {
                  // see we can satisfy the request from our cache
                  ZoteroCollection cached = responseFromServerCache(conn.type, conn.cacheContext, webCollection.name, cacheSpecs);
                  if (!cached.empty())
                  {
                     responseCollections.push_back(cached);
                  }
                  else
                  {
                     // shouldn't be possible to get here (as the initial condition tested in the loop ensures
                     // that we have a cached collection)
                     TRACE("Unexpected failure to find cache for " + webCollection.name);
                  }
               }
            }

            handler(Success(), responseCollections, warning);

         // for host errors try to serve from the cache
         } else if (isHostError(core::errorDescription(error))) {

            ZoteroCollections responseCollections;
            for (auto collection : collections)
            {
               ZoteroCollection cached = responseFromServerCache(conn.type, conn.cacheContext, collection, cacheSpecs);
               if (!cached.empty())
                  responseCollections.push_back(cached);
            }
            handler(Success(),responseCollections, warning);

         // report error
         } else {
            handler(error, std::vector<ZoteroCollection>(), warning);
         }

      });
   }
   else
   {
      handler(Success(), std::vector<ZoteroCollection>(), "");
   }

}

} // end namespace collections
} // end namespace zotero
} // end namespace modules
} // end namespace session
} // end namespace rstudio
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * 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.
 *
 * Authors: Gabe Black
 */

#ifndef __ARCH_ALPHA_PREDECODER_HH__
#define __ARCH_ALPHA_PREDECODER_HH__

#include "arch/alpha/types.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "sim/host.hh"

class ThreadContext;

namespace AlphaISA
{
    class Predecoder
    {
      protected:
        ThreadContext * tc;
        //The extended machine instruction being generated
        ExtMachInst ext_inst;

      public:
        Predecoder(ThreadContext * _tc) : tc(_tc)
        {}

        ThreadContext * getTC()
        {
            return tc;
        }

        void setTC(ThreadContext * _tc)
        {
            tc = _tc;
        }

        void process()
        {
        }

        void reset()
        {}

        //Use this to give data to the predecoder. This should be used
        //when there is control flow.
        void moreBytes(Addr pc, Addr fetchPC, MachInst inst)
        {
            ext_inst = inst;
#if FULL_SYSTEM
            if (pc && 0x1)
                ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
#endif
        }

        bool needMoreBytes()
        {
            return true;
        }

        bool extMachInstReady()
        {
            return true;
        }

        //This returns a constant reference to the ExtMachInst to avoid a copy
        const ExtMachInst & getExtMachInst()
        {
            return ext_inst;
        }
    };
};

#endif // __ARCH_ALPHA_PREDECODER_HH__
<commit_msg>Alpha: Fix a long standing bug where all code ran as PAL code in FS.<commit_after>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * 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.
 *
 * Authors: Gabe Black
 */

#ifndef __ARCH_ALPHA_PREDECODER_HH__
#define __ARCH_ALPHA_PREDECODER_HH__

#include "arch/alpha/types.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "sim/host.hh"

class ThreadContext;

namespace AlphaISA
{
    class Predecoder
    {
      protected:
        ThreadContext * tc;
        //The extended machine instruction being generated
        ExtMachInst ext_inst;

      public:
        Predecoder(ThreadContext * _tc) : tc(_tc)
        {}

        ThreadContext * getTC()
        {
            return tc;
        }

        void setTC(ThreadContext * _tc)
        {
            tc = _tc;
        }

        void process()
        {
        }

        void reset()
        {}

        //Use this to give data to the predecoder. This should be used
        //when there is control flow.
        void moreBytes(Addr pc, Addr fetchPC, MachInst inst)
        {
            ext_inst = inst;
#if FULL_SYSTEM
            ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
#endif
        }

        bool needMoreBytes()
        {
            return true;
        }

        bool extMachInstReady()
        {
            return true;
        }

        //This returns a constant reference to the ExtMachInst to avoid a copy
        const ExtMachInst & getExtMachInst()
        {
            return ext_inst;
        }
    };
};

#endif // __ARCH_ALPHA_PREDECODER_HH__
<|endoftext|>