<commit_before>// Copyright 2017-2020 The Verible Authors.
//
// 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 <deque>
#include <fstream>
#include <iostream>
#include <string>

#include "absl/flags/flag.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "common/util/bijective_map.h"
#include "common/util/enum_flags.h"
#include "common/util/file_util.h"
#include "common/util/init_command_line.h"
#include "google/protobuf/io/zero_copy_stream_impl.h"
#include "kythe/cxx/common/indexing/KytheCachingOutput.h"
#include "kythe/proto/storage.pb.h"
#include "verilog/analysis/verilog_analyzer.h"
#include "verilog/analysis/verilog_project.h"
#include "verilog/tools/kythe/indexing_facts_tree_extractor.h"
#include "verilog/tools/kythe/kythe_facts_extractor.h"

// for --print_kythe_facts flag
enum class PrintMode {
  kJSON,
  kJSONDebug,
  kProto,
};

static const verible::EnumNameMap<PrintMode> kPrintModeStringMap{{
    {"json", PrintMode::kJSON},
    {"json_debug", PrintMode::kJSONDebug},
    {"proto", PrintMode::kProto},
}};

static std::ostream& operator<<(std::ostream& stream, PrintMode mode) {
  return kPrintModeStringMap.Unparse(mode, stream);
}

static bool AbslParseFlag(absl::string_view text, PrintMode* mode,
                          std::string* error) {
  return kPrintModeStringMap.Parse(text, mode, error,
                                   "--print_kythe_facts value");
}

static std::string AbslUnparseFlag(const PrintMode& mode) {
  std::ostringstream stream;
  stream << mode;
  return stream.str();
}

ABSL_FLAG(bool, printextraction, false,
          "Whether or not to print the extracted general indexing facts tree "
          "from the middle layer)");

ABSL_FLAG(
    PrintMode, print_kythe_facts, PrintMode::kJSON,
    "Determines how to print Kythe indexing facts.  Options:\n"
    "  json: Outputs Kythe facts in JSON format (one per line)\n"
    "  json_debug: Outputs Kythe facts in JSON format (without encoding, all in one JSON object)\n"
    "  proto: Outputs Kythe facts in proto format\n"
    "Default: json\n");

ABSL_FLAG(
    std::string, file_list_path, "",
    R"(The path to the file list which contains the names of SystemVerilog files.
    The files should be ordered by definition dependencies.)");

ABSL_FLAG(
    std::string, file_list_root, ".",
    R"(The absolute location which we prepend to the files in the file list (where listed files are relative to).)");

// TODO: support repeatable flag
ABSL_FLAG(
    std::vector<std::string>, include_dir_paths, {},
    R"(Comma separated paths of the directories used to look for included files.
Note: The order of the files here is important.
File search will stop at the the first found among the listed directories.
e.g --include_dir_paths directory1,directory2
if "A.sv" exists in both "directory1" and "directory2" the one in "directory1" is the one we will use.
)");

namespace verilog {
namespace kythe {

// Prints Kythe facts in proto format to stdout.
static void PrintKytheFactsProtoEntries(
    const IndexingFactNode& file_list_facts_tree,
    const VerilogProject& project) {
  google::protobuf::io::FileOutputStream file_output(STDOUT_FILENO);
  file_output.SetCloseOnDelete(true);
  ::kythe::FileOutputStream kythe_output(&file_output);
  kythe_output.set_flush_after_each_entry(true);

  StreamKytheFactsProtoEntries(&kythe_output, file_list_facts_tree, project);
}

static std::vector<absl::Status> ExtractTranslationUnits(
    absl::string_view file_list_path, VerilogProject* project,
    const std::vector<std::string>& file_names) {
  const verilog::kythe::IndexingFactNode file_list_facts_tree(
      verilog::kythe::ExtractFiles(file_list_path, project, file_names));

  // check for printextraction flag, and print extraction if on
  if (absl::GetFlag(FLAGS_printextraction)) {
    // Don't use std::cout unless KytheFactsPrinter uses another stream.
    LOG(INFO) << file_list_facts_tree << std::endl;
  }

  // check how to output kythe facts.
  switch (absl::GetFlag(FLAGS_print_kythe_facts)) {
    case PrintMode::kJSON: {
      std::cout << KytheFactsPrinter(file_list_facts_tree, *project)
                << std::endl;
      break;
    }
    case PrintMode::kJSONDebug: {
      std::cout << KytheFactsPrinter(file_list_facts_tree, *project,
                                     /*debug=*/true)
                << std::endl;
      break;
    }
    case PrintMode::kProto: {
      PrintKytheFactsProtoEntries(file_list_facts_tree, *project);
      break;
    }
  }

  return project->GetErrorStatuses();
}

}  // namespace kythe
}  // namespace verilog

int main(int argc, char** argv) {
  const auto usage =
      absl::StrCat("usage: ", argv[0], " [options] --file_list_path FILE\n", R"(
Extracts kythe indexing facts from the given SystemVerilog source files.

Input: A file which lists paths to the SystemVerilog top-level translation
       unit files (one per line; the path is relative to the location of the
       file list).
Output: Produces Indexing Facts for kythe (http://kythe.io).
)");
  const auto args = verible::InitCommandLine(usage, &argc, &argv);

  // List of the directories for where to look for included files.
  const std::vector<std::string> include_dir_paths =
      absl::GetFlag(FLAGS_include_dir_paths);

  const std::string file_list_path = absl::GetFlag(FLAGS_file_list_path);
  if (file_list_path.empty()) {
    LOG(ERROR) << "No file list path was specified";
    return 1;
  }
  const std::string file_list_root = absl::GetFlag(FLAGS_file_list_root);

  // Load file list.
  const auto files_names_or_status(
      verilog::ParseSourceFileListFromFile(file_list_path));
  if (!files_names_or_status.ok()) {
    LOG(ERROR) << "Error while reading file list: "
               << files_names_or_status.status().message();
    return 1;
  }
  const std::vector<std::string>& files_names(*files_names_or_status);

  verilog::VerilogProject project(file_list_root, include_dir_paths);

  const std::vector<absl::Status> errors(
      verilog::kythe::ExtractTranslationUnits(file_list_path, &project,
                                              files_names));
  if (!errors.empty()) {
    LOG(ERROR) << "Encountered some issues while indexing files (could result "
                  "in missing indexing data):"
               << std::endl;
    for (const auto& error : errors) {
      LOG(ERROR) << error.message();
    }
    // TODO(ikr): option to cause any errors to exit non-zero, like
    // (bool) --index_files_fatal.  This can signal to user/caller that
    // something went wrong, and surface errors.
  }
  return 0;
}
<commit_msg>[kythe] fix formatting of verilog/tools/kythe/verilog_kythe_extractor.cc<commit_after>// Copyright 2017-2020 The Verible Authors.
//
// 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 <deque>
#include <fstream>
#include <iostream>
#include <string>

#include "absl/flags/flag.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "common/util/bijective_map.h"
#include "common/util/enum_flags.h"
#include "common/util/file_util.h"
#include "common/util/init_command_line.h"
#include "google/protobuf/io/zero_copy_stream_impl.h"
#include "kythe/cxx/common/indexing/KytheCachingOutput.h"
#include "kythe/proto/storage.pb.h"
#include "verilog/analysis/verilog_analyzer.h"
#include "verilog/analysis/verilog_project.h"
#include "verilog/tools/kythe/indexing_facts_tree_extractor.h"
#include "verilog/tools/kythe/kythe_facts_extractor.h"

// for --print_kythe_facts flag
enum class PrintMode {
  kJSON,
  kJSONDebug,
  kProto,
};

static const verible::EnumNameMap<PrintMode> kPrintModeStringMap{{
    {"json", PrintMode::kJSON},
    {"json_debug", PrintMode::kJSONDebug},
    {"proto", PrintMode::kProto},
}};

static std::ostream& operator<<(std::ostream& stream, PrintMode mode) {
  return kPrintModeStringMap.Unparse(mode, stream);
}

static bool AbslParseFlag(absl::string_view text, PrintMode* mode,
                          std::string* error) {
  return kPrintModeStringMap.Parse(text, mode, error,
                                   "--print_kythe_facts value");
}

static std::string AbslUnparseFlag(const PrintMode& mode) {
  std::ostringstream stream;
  stream << mode;
  return stream.str();
}

ABSL_FLAG(bool, printextraction, false,
          "Whether or not to print the extracted general indexing facts tree "
          "from the middle layer)");

ABSL_FLAG(PrintMode, print_kythe_facts, PrintMode::kJSON,
          "Determines how to print Kythe indexing facts.  Options:\n"
          "  json: Outputs Kythe facts in JSON format (one per line)\n"
          "  json_debug: Outputs Kythe facts in JSON format (without encoding, "
          "all in one JSON object)\n"
          "  proto: Outputs Kythe facts in proto format\n"
          "Default: json\n");

ABSL_FLAG(
    std::string, file_list_path, "",
    R"(The path to the file list which contains the names of SystemVerilog files.
    The files should be ordered by definition dependencies.)");

ABSL_FLAG(
    std::string, file_list_root, ".",
    R"(The absolute location which we prepend to the files in the file list (where listed files are relative to).)");

// TODO: support repeatable flag
ABSL_FLAG(
    std::vector<std::string>, include_dir_paths, {},
    R"(Comma separated paths of the directories used to look for included files.
Note: The order of the files here is important.
File search will stop at the the first found among the listed directories.
e.g --include_dir_paths directory1,directory2
if "A.sv" exists in both "directory1" and "directory2" the one in "directory1" is the one we will use.
)");

namespace verilog {
namespace kythe {

// Prints Kythe facts in proto format to stdout.
static void PrintKytheFactsProtoEntries(
    const IndexingFactNode& file_list_facts_tree,
    const VerilogProject& project) {
  google::protobuf::io::FileOutputStream file_output(STDOUT_FILENO);
  file_output.SetCloseOnDelete(true);
  ::kythe::FileOutputStream kythe_output(&file_output);
  kythe_output.set_flush_after_each_entry(true);

  StreamKytheFactsProtoEntries(&kythe_output, file_list_facts_tree, project);
}

static std::vector<absl::Status> ExtractTranslationUnits(
    absl::string_view file_list_path, VerilogProject* project,
    const std::vector<std::string>& file_names) {
  const verilog::kythe::IndexingFactNode file_list_facts_tree(
      verilog::kythe::ExtractFiles(file_list_path, project, file_names));

  // check for printextraction flag, and print extraction if on
  if (absl::GetFlag(FLAGS_printextraction)) {
    // Don't use std::cout unless KytheFactsPrinter uses another stream.
    LOG(INFO) << file_list_facts_tree << std::endl;
  }

  // check how to output kythe facts.
  switch (absl::GetFlag(FLAGS_print_kythe_facts)) {
    case PrintMode::kJSON: {
      std::cout << KytheFactsPrinter(file_list_facts_tree, *project)
                << std::endl;
      break;
    }
    case PrintMode::kJSONDebug: {
      std::cout << KytheFactsPrinter(file_list_facts_tree, *project,
                                     /*debug=*/true)
                << std::endl;
      break;
    }
    case PrintMode::kProto: {
      PrintKytheFactsProtoEntries(file_list_facts_tree, *project);
      break;
    }
  }

  return project->GetErrorStatuses();
}

}  // namespace kythe
}  // namespace verilog

int main(int argc, char** argv) {
  const auto usage =
      absl::StrCat("usage: ", argv[0], " [options] --file_list_path FILE\n", R"(
Extracts kythe indexing facts from the given SystemVerilog source files.

Input: A file which lists paths to the SystemVerilog top-level translation
       unit files (one per line; the path is relative to the location of the
       file list).
Output: Produces Indexing Facts for kythe (http://kythe.io).
)");
  const auto args = verible::InitCommandLine(usage, &argc, &argv);

  // List of the directories for where to look for included files.
  const std::vector<std::string> include_dir_paths =
      absl::GetFlag(FLAGS_include_dir_paths);

  const std::string file_list_path = absl::GetFlag(FLAGS_file_list_path);
  if (file_list_path.empty()) {
    LOG(ERROR) << "No file list path was specified";
    return 1;
  }
  const std::string file_list_root = absl::GetFlag(FLAGS_file_list_root);

  // Load file list.
  const auto files_names_or_status(
      verilog::ParseSourceFileListFromFile(file_list_path));
  if (!files_names_or_status.ok()) {
    LOG(ERROR) << "Error while reading file list: "
               << files_names_or_status.status().message();
    return 1;
  }
  const std::vector<std::string>& files_names(*files_names_or_status);

  verilog::VerilogProject project(file_list_root, include_dir_paths);

  const std::vector<absl::Status> errors(
      verilog::kythe::ExtractTranslationUnits(file_list_path, &project,
                                              files_names));
  if (!errors.empty()) {
    LOG(ERROR) << "Encountered some issues while indexing files (could result "
                  "in missing indexing data):"
               << std::endl;
    for (const auto& error : errors) {
      LOG(ERROR) << error.message();
    }
    // TODO(ikr): option to cause any errors to exit non-zero, like
    // (bool) --index_files_fatal.  This can signal to user/caller that
    // something went wrong, and surface errors.
  }
  return 0;
}
<|endoftext|>


<commit_before>#include "types.h"
#include "kernel.h"
#include "kernel_version.h"
#include "idt.h"
#include "timer.h"
#include "kb.h"
#include "mm.h"
#include "fb.h"
#include "ata.hh"
#include "processmanager.h"
#include "task.h"
#include "syscall.hh"
#include "fs/vfs.hh"
#include "fs/devfs.hh"
#include "fs/clothesfs.hh"

#ifdef ARCH_LINUX
#include "arch/linux/virtualdisc.h"
#endif

extern "C" int main(int argc, char **argv);
void app_proc()
{
    int argc = 1;
    char *appname = (char*)MM::instance()->alloc(4);
    Mem::copy(appname, "app", 4);
    char * argv[] = {
        appname,
        NULL
    };

    int res = main(argc, argv);
    Platform::video()->printf("\n\nApplication exit with code: %d\nHalting...\n", res);

    MM::instance()->free(appname);

    while (true) {
        //Timer::get()->wait(500);
    }
}

void kernel_loop()
{
#if 1
    ProcessManager *pm = Platform::processManager();

    Task *a_task = Platform::task()->create((ptr_val_t)&app_proc, 0, 0);
    a_task->setName("Application main");
    pm->addTask(a_task);
    a_task->setPriority(40);

#if 0
    Task *a_task = Platform::task()->create((ptr_val_t)&A_proc, 0, 0);
    Task *b_task = Platform::task()->create((ptr_val_t)&B_proc, 0, 0);
    Task *c_task = Platform::task()->create((ptr_val_t)&C_proc, 0, 0);

    a_task->setName("A task");
    a_task->setSize(100);
    a_task->setPriority(40);

    b_task->setName("B task");
    b_task->setNice(10);

    c_task->setPriority(10);
    c_task->setName("C task");

    pm->addTask(a_task);
    pm->addTask(b_task);
    pm->addTask(c_task);
#endif
#endif

    uint32_t start = Platform::timer()->getTicks();
    (void)start;
    while (1) {
        //FIXME
#if 0
        uint32_t end = Platform::timer()->getTicks();
        Platform::video()->printf("Diff: %d\n",end-start);
#endif
#if 0
        ProcessManager *pm = Platform::processManager();
        pm->schedule();
#endif
#ifdef FEATURE_GRAPHICS
        if (Platform::fb()!=NULL && Platform::fb()->isConfigured()) {
                Platform::fb()->swap();
                Platform::fb()->blit();
        }
#endif

        /* Update screen */
        Timer::get()->wait(1);
    }
}

Kernel::Kernel()
{
    platform = new Platform();
    video = Video::get();

    if (IDT::get() == NULL) {
        delete platform;
        delete video;
        video = NULL;
        platform = NULL;
        return;
    }
    IDT::get()->initISR();
    IDT::get()->initIRQ();

    if (Timer::get() == NULL) {
        delete platform;
        delete video;
        video = NULL;
        platform = NULL;
        return;
    }
    vfs = NULL;
    pcidev = NULL;
    pmanager = NULL;

    Timer::get()->setFrequency(KERNEL_FREQUENCY);
    KB::get();
}

Kernel::~Kernel()
{
    delete video;
    video = NULL;
}

// XXX
#ifdef ARCH_ARM
#include "arch/arm/gpio.h"
#endif

void Kernel::initVideo()
{
    if (video != NULL) {
        video->clear();
#if 0
        video->printf("Ticks: %lu!\n",Timer::get()->getTicks());
        video->printf("Hello world!\n");
#endif
        video->printf("\nC++ kernel %s!!!\n\n", kernel_version);
#if 0
        video->printf("And a TAB\t test!\n");
        video->printf("Removing letter A\bB and continuing.\n");
        video->printf("\b\b\bABCDEFG\n");
        video->printf("Ticks: %lu!\n",Timer::get()->getTicks());
#endif

#if 0
        /* Some random timing... */
        volatile int b = 5;
        for (int i=0; i<0x1FFFFFF; i++) { b = b + i; }
        video->printf("Ticks: %lu!\n",Timer::get()->getTicks());
        for (int i=0; i<0x1FFFFF; i++) { b = b + i; }
        video->printf("Ticks: %lu!\n",Timer::get()->getTicks());
#endif
    }
}

void Kernel::initFileSystem()
{
    vfs = Platform::vfs();
    vfs->register_filesystem(new DevFS);
    vfs->mount("/dev", "DevFS", "");
}

void Kernel::initPCI()
{
#ifdef FEATURE_STORAGE
    PCI *pcidev = Platform::pci();
    if (pcidev != NULL) {
        if (pcidev->isAvailable()) video->printf("Found PCI\n");
        else video->printf("PCI not available\n");
        pcidev->setVerbose();
        pcidev->scanDevices();
    }
#endif
}

void Kernel::initATA(Filesystem *cfs)
{
#ifdef FEATURE_STORAGE
    ATA *ata = Platform::ata();
    if (ata != NULL) {
        ata->init();
        ATA::Device *dev = ata->getDevice();
        bool mounted = false;
        while (dev != NULL) {
            video->printf("dev %x...\n", dev);
            if ((ata->deviceModel(dev) == ATA::STORAGE_SATA
                || ata->deviceModel(dev) == ATA::STORAGE_PATA)
                && ata->deviceSize(dev) > 0) {
                if (!mounted) {
                    video->printf("Mounting...\n");
                    ATAPhys *ataphys = new ATAPhys(dev);
                    cfs->setPhysical(ataphys);
                    vfs->register_filesystem(cfs);
                    vfs->mount("/cfs", "ClothesFS", "");
                    mounted = true;
                    video->printf("Mounted\n");
                }
                break;
            }

            dev = ata->nextDevice(dev);
        }
    }
#endif
}

void Kernel::initVirtualDisc()
{
#ifdef ARCH_LINUX
#ifdef FEATURE_STORAGE
    VirtualDisc *vd = new VirtualDisc();
    vd->append("test.img");
    ATA::Device *dev = vd->getDevice();
    uint8_t buffer[512];
    if (dev != NULL) {
        video->printf("Reading...\n");
        for (uint32_t sec=0; sec<6; sec++) {
            if (vd->read(dev, buffer, 1,  sec)) {
                video->printf("VIRTUAL: Ok %d. %x %x %x\n", sec, buffer[0], buffer[1], buffer[2]);
            }
        }
        video->printf("Done.\n");
    }
#endif
#endif
}

void Kernel::drawTestData()
{
#ifdef FEATURE_GRAPHICS
    video->printf("FB3.2\n");
    platform->fb()->swap();
    platform->fb()->blit();
#if 1
    for (int j=0; j<120; j++) {
        platform->fb()->putPixel(j,10,255,255,255);
    }
    platform->fb()->swap();
    platform->fb()->blit();
    video->printf("FB5\n");
#if 1
    for (int j=100; j<120; j++) {
        for (int i=100; i<200; i++) {
            platform->fb()->putPixel(i,100+j,255,0,0);
            platform->fb()->putPixel(j,100+i,0,0,255);
        }
    }
#endif
#endif
#endif
}

int Kernel::initFrameBuffer()
{
#ifdef FEATURE_GRAPHICS
    FB::ModeConfig conf;
    conf.width=800;
    conf.height=600;
    conf.depth=24;

    //FB::ModeConfig *vconf = platform->fb()->query(NULL);
    if (platform->fb()==NULL) return 1;

    FB::ModeConfig *vconf = platform->fb()->query(&conf);
    if (vconf != NULL) {
        video->printf("FB3\n");
        platform->fb()->configure(vconf);

        // TODO: Can be removed
        drawTestData();

#if 1
        video->printf("C++ test kernel\n");
        platform->fb()->swap();
        platform->fb()->blit();
#endif
    }
#endif
    return 0;
}

void Kernel::startProcessManager()
{
    pmanager = Platform::processManager();
    if (pmanager != NULL && Platform::task() != NULL) {
        Task *kernel_task = Platform::task()->create((ptr_val_t)kernel_loop, 0, 0);
        kernel_task->setSize(2);
        kernel_task->setNice(40);

        pmanager->setRunning();
        pmanager->addTask(kernel_task);
    }
}

void Kernel::initSysCall()
{
    sys = new SysCall();
}

int Kernel::run()
{
    if (platform == NULL) {
        return 1;
    }
    if (platform->state() == NULL) {
        return 1;
    }
    platform->state()->startInterrupts();

    initVideo();

    initFileSystem();

    initPCI();

    ClothesFilesystem *cfs = new ClothesFilesystem;

    initATA(cfs);

    initVirtualDisc();

    int res = initFrameBuffer();
    if (res != 0) {
        return res;
    }

    initSysCall();

    startProcessManager();

    //TODO: Setup initial task
    while(1) {}

    return 0;
}
<commit_msg>Clean more<commit_after>#include "types.h"
#include "kernel.h"
#include "kernel_version.h"
#include "idt.h"
#include "timer.h"
#include "kb.h"
#include "mm.h"
#include "fb.h"
#include "ata.hh"
#include "processmanager.h"
#include "task.h"
#include "syscall.hh"
#include "fs/vfs.hh"
#include "fs/devfs.hh"
#include "fs/clothesfs.hh"

#ifdef ARCH_LINUX
#include "arch/linux/virtualdisc.h"
#endif

extern "C" int main(int argc, char **argv);
void app_proc()
{
    int argc = 1;
    char *appname = (char*)MM::instance()->alloc(4);
    Mem::copy(appname, "app", 4);
    char * argv[] = {
        appname,
        NULL
    };

    int res = main(argc, argv);
    Platform::video()->printf("\n\nApplication exit with code: %d\nHalting...\n", res);

    MM::instance()->free(appname);

    while (true) {
        //Timer::get()->wait(500);
    }
}

void kernel_loop()
{
#if 1
    ProcessManager *pm = Platform::processManager();

    Task *a_task = Platform::task()->create((ptr_val_t)&app_proc, 0, 0);
    a_task->setName("Application main");
    pm->addTask(a_task);
    a_task->setPriority(40);
#endif

    uint32_t start = Platform::timer()->getTicks();
    (void)start;
    while (1) {
        //FIXME
#if 0
        uint32_t end = Platform::timer()->getTicks();
        Platform::video()->printf("Diff: %d\n",end-start);
#endif
#if 0
        ProcessManager *pm = Platform::processManager();
        pm->schedule();
#endif
#ifdef FEATURE_GRAPHICS
        if (Platform::fb()!=NULL && Platform::fb()->isConfigured()) {
                Platform::fb()->swap();
                Platform::fb()->blit();
        }
#endif

        /* Update screen */
        Timer::get()->wait(1);
    }
}

Kernel::Kernel()
{
    platform = new Platform();
    video = Video::get();

    if (IDT::get() == NULL) {
        delete platform;
        delete video;
        video = NULL;
        platform = NULL;
        return;
    }
    IDT::get()->initISR();
    IDT::get()->initIRQ();

    if (Timer::get() == NULL) {
        delete platform;
        delete video;
        video = NULL;
        platform = NULL;
        return;
    }
    vfs = NULL;
    pcidev = NULL;
    pmanager = NULL;

    Timer::get()->setFrequency(KERNEL_FREQUENCY);
    KB::get();
}

Kernel::~Kernel()
{
    delete video;
    video = NULL;
}

// XXX
#ifdef ARCH_ARM
#include "arch/arm/gpio.h"
#endif

void Kernel::initVideo()
{
    if (video != NULL) {
        video->clear();
#if 0
        video->printf("Ticks: %lu!\n",Timer::get()->getTicks());
        video->printf("Hello world!\n");
#endif
        video->printf("\nC++ kernel %s!!!\n\n", kernel_version);
#if 0
        video->printf("And a TAB\t test!\n");
        video->printf("Removing letter A\bB and continuing.\n");
        video->printf("\b\b\bABCDEFG\n");
        video->printf("Ticks: %lu!\n",Timer::get()->getTicks());
#endif

#if 0
        /* Some random timing... */
        volatile int b = 5;
        for (int i=0; i<0x1FFFFFF; i++) { b = b + i; }
        video->printf("Ticks: %lu!\n",Timer::get()->getTicks());
        for (int i=0; i<0x1FFFFF; i++) { b = b + i; }
        video->printf("Ticks: %lu!\n",Timer::get()->getTicks());
#endif
    }
}

void Kernel::initFileSystem()
{
    vfs = Platform::vfs();
    vfs->register_filesystem(new DevFS);
    vfs->mount("/dev", "DevFS", "");
}

void Kernel::initPCI()
{
#ifdef FEATURE_STORAGE
    PCI *pcidev = Platform::pci();
    if (pcidev != NULL) {
        if (pcidev->isAvailable()) video->printf("Found PCI\n");
        else video->printf("PCI not available\n");
        pcidev->setVerbose();
        pcidev->scanDevices();
    }
#endif
}

void Kernel::initATA(Filesystem *cfs)
{
#ifdef FEATURE_STORAGE
    ATA *ata = Platform::ata();
    if (ata != NULL) {
        ata->init();
        ATA::Device *dev = ata->getDevice();
        bool mounted = false;
        while (dev != NULL) {
            video->printf("dev %x...\n", dev);
            if ((ata->deviceModel(dev) == ATA::STORAGE_SATA
                || ata->deviceModel(dev) == ATA::STORAGE_PATA)
                && ata->deviceSize(dev) > 0) {
                if (!mounted) {
                    video->printf("Mounting...\n");
                    ATAPhys *ataphys = new ATAPhys(dev);
                    cfs->setPhysical(ataphys);
                    vfs->register_filesystem(cfs);
                    vfs->mount("/cfs", "ClothesFS", "");
                    mounted = true;
                    video->printf("Mounted\n");
                }
                break;
            }

            dev = ata->nextDevice(dev);
        }
    }
#endif
}

void Kernel::initVirtualDisc()
{
#ifdef ARCH_LINUX
#ifdef FEATURE_STORAGE
    VirtualDisc *vd = new VirtualDisc();
    vd->append("test.img");
    ATA::Device *dev = vd->getDevice();
    uint8_t buffer[512];
    if (dev != NULL) {
        video->printf("Reading...\n");
        for (uint32_t sec=0; sec<6; sec++) {
            if (vd->read(dev, buffer, 1,  sec)) {
                video->printf("VIRTUAL: Ok %d. %x %x %x\n", sec, buffer[0], buffer[1], buffer[2]);
            }
        }
        video->printf("Done.\n");
    }
#endif
#endif
}

void Kernel::drawTestData()
{
#ifdef FEATURE_GRAPHICS
    video->printf("FB3.2\n");
    platform->fb()->swap();
    platform->fb()->blit();
#if 1
    for (int j=0; j<120; j++) {
        platform->fb()->putPixel(j,10,255,255,255);
    }
    platform->fb()->swap();
    platform->fb()->blit();
    video->printf("FB5\n");
#if 1
    for (int j=100; j<120; j++) {
        for (int i=100; i<200; i++) {
            platform->fb()->putPixel(i,100+j,255,0,0);
            platform->fb()->putPixel(j,100+i,0,0,255);
        }
    }
#endif
#endif
#endif
}

int Kernel::initFrameBuffer()
{
#ifdef FEATURE_GRAPHICS
    FB::ModeConfig conf;
    conf.width=800;
    conf.height=600;
    conf.depth=24;

    //FB::ModeConfig *vconf = platform->fb()->query(NULL);
    if (platform->fb()==NULL) return 1;

    FB::ModeConfig *vconf = platform->fb()->query(&conf);
    if (vconf != NULL) {
        video->printf("FB3\n");
        platform->fb()->configure(vconf);

        // TODO: Can be removed
        drawTestData();

#if 1
        video->printf("C++ test kernel\n");
        platform->fb()->swap();
        platform->fb()->blit();
#endif
    }
#endif
    return 0;
}

void Kernel::startProcessManager()
{
    ProcessManager *pmanager = Platform::processManager();
    if (pmanager != NULL && Platform::task() != NULL) {
        Task *kernel_task = Platform::task()->create((ptr_val_t)kernel_loop, 0, 0);
        kernel_task->setSize(2);
        kernel_task->setNice(40);

        pmanager->setRunning();
        pmanager->addTask(kernel_task);
    }
}

void Kernel::initSysCall()
{
    sys = new SysCall();
}

int Kernel::run()
{
    if (platform == NULL) {
        return 1;
    }
    if (platform->state() == NULL) {
        return 1;
    }
    platform->state()->startInterrupts();

    initVideo();

    initFileSystem();

    initPCI();

    ClothesFilesystem *cfs = new ClothesFilesystem;

    initATA(cfs);

    initVirtualDisc();

    int res = initFrameBuffer();
    if (res != 0) {
        return res;
    }

    initSysCall();

    startProcessManager();

    //TODO: Setup initial task
    while(1) {}

    return 0;
}
<|endoftext|>


<commit_before>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "base/desktop/screen_capturer_dxgi.h"

#include "base/logging.h"
#include "base/desktop/win/screen_capture_utils.h"
#include "base/ipc/shared_memory_factory.h"
#include "base/strings/unicode.h"

namespace base {

namespace {

bool screenListFromDeviceNames(const std::vector<std::wstring>& device_names,
                               ScreenCapturer::ScreenList* screens)
{
    DCHECK(screens->empty());

    ScreenCapturer::ScreenList gdi_screens;

    if (!ScreenCaptureUtils::screenList(&gdi_screens))
        return false;

    ScreenCapturer::ScreenId max_screen_id = -1;

    for (const auto& screen : gdi_screens)
        max_screen_id = std::max(max_screen_id, screen.id);

    for (const auto& device_name : device_names)
    {
        bool device_found = false;

        for (const auto& gdi_screen : gdi_screens)
        {
            std::string device_name_utf8 = utf8FromWide(device_name);

            if (gdi_screen.title == device_name_utf8)
            {
                screens->push_back(gdi_screen);
                device_found = true;

                break;
            }
        }

        if (!device_found)
        {
            // devices_names[i] has not been found in gdi_names, so use max_screen_id.
            ++max_screen_id;
            screens->push_back({ max_screen_id, std::string() });
        }
    }

    return true;
}

int indexFromScreenId(ScreenCapturer::ScreenId id, const std::vector<std::wstring>& device_names)
{
    ScreenCapturer::ScreenList screens;

    if (!screenListFromDeviceNames(device_names, &screens))
    {
        LOG(LS_WARNING) << "screenListFromDeviceNames failed";
        return -1;
    }

    DCHECK_EQ(device_names.size(), screens.size());

    for (size_t i = 0; i < screens.size(); ++i)
    {
        if (screens[i].id == id)
            return static_cast<int>(i);
    }

    LOG(LS_WARNING) << "Screen with ID " << id << " not found";
    return -1;
}

} // namespace

ScreenCapturerDxgi::ScreenCapturerDxgi()
    : ScreenCapturer(Type::WIN_DXGI),
      controller_(std::make_shared<DxgiDuplicatorController>())
{
    LOG(LS_INFO) << "ScreenCapturerDxgi Ctor";
}

ScreenCapturerDxgi::~ScreenCapturerDxgi()
{
    LOG(LS_INFO) << "ScreenCapturerDxgi Dtor";
}

bool ScreenCapturerDxgi::isSupported()
{
    // Forwards isSupported() function call to DxgiDuplicatorController.
    return controller_->isSupported();
}

// static
bool ScreenCapturerDxgi::isCurrentSessionSupported()
{
    return DxgiDuplicatorController::isCurrentSessionSupported();
}

int ScreenCapturerDxgi::screenCount()
{
    return controller_->screenCount();
}

bool ScreenCapturerDxgi::screenList(ScreenList* screens)
{
    std::vector<std::wstring> device_names;

    if (!controller_->deviceNames(&device_names))
    {
        LOG(LS_WARNING) << "deviceNames failed";
        return false;
    }

    return screenListFromDeviceNames(device_names, screens);
}

bool ScreenCapturerDxgi::selectScreen(ScreenId screen_id)
{
    LOG(LS_INFO) << "Select screen with ID: " << screen_id;

    if (screen_id == kFullDesktopScreenId)
    {
        current_screen_id_ = screen_id;
        return true;
    }

    std::vector<std::wstring> device_names;

    if (!controller_->deviceNames(&device_names))
    {
        LOG(LS_WARNING) << "deviceNames failed";
        return false;
    }

    int index = indexFromScreenId(screen_id, device_names);
    if (index == -1)
    {
        LOG(LS_WARNING) << "indexFromScreenId failed";
        return false;
    }

    current_screen_id_ = index;
    return true;
}

const Frame* ScreenCapturerDxgi::captureFrame(Error* error)
{
    DCHECK(error);

    queue_.moveToNextFrame();

    if (!queue_.currentFrame())
    {
        queue_.replaceCurrentFrame(
            std::make_unique<DxgiFrame>(controller_, sharedMemoryFactory()));
    }

    DxgiDuplicatorController::Result result;

    if (current_screen_id_ == kFullDesktopScreenId)
        result = controller_->duplicate(queue_.currentFrame());
    else
        result = controller_->duplicateMonitor(queue_.currentFrame(), current_screen_id_);

    using DuplicateResult = DxgiDuplicatorController::Result;

    if (result != DuplicateResult::SUCCEEDED)
    {
        LOG(LS_ERROR) << "DxgiDuplicatorController failed to capture desktop, error code "
                      << DxgiDuplicatorController::resultName(result);
    }

    switch (result)
    {
        case DuplicateResult::SUCCEEDED:
        {
            *error = Error::SUCCEEDED;
            return queue_.currentFrame()->frame();
        }

        case DuplicateResult::UNSUPPORTED_SESSION:
        {
            LOG(LS_ERROR) << "Current binary is running on a session not supported "
                             "by DirectX screen capturer";
            *error = Error::PERMANENT;
            return nullptr;
        }

        case DuplicateResult::FRAME_PREPARE_FAILED:
        {
            LOG(LS_ERROR) << "Failed to allocate a new Frame";
            // This usually means we do not have enough memory or SharedMemoryFactory cannot work
            // correctly.
            *error = Error::PERMANENT;
            return nullptr;
        }

        case DuplicateResult::INVALID_MONITOR_ID:
        {
            LOG(LS_ERROR) << "Invalid monitor id " << current_screen_id_;
            *error = Error::PERMANENT;
            return nullptr;
        }

        case DuplicateResult::INITIALIZATION_FAILED:
        case DuplicateResult::DUPLICATION_FAILED:
        default:
        {
            *error = Error::TEMPORARY;
            return nullptr;
        }
    }
}

void ScreenCapturerDxgi::reset()
{
    queue_.reset();
}

} // namespace base
<commit_msg>Added debug messages.<commit_after>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "base/desktop/screen_capturer_dxgi.h"

#include "base/logging.h"
#include "base/desktop/win/screen_capture_utils.h"
#include "base/ipc/shared_memory_factory.h"
#include "base/strings/unicode.h"

namespace base {

namespace {

bool screenListFromDeviceNames(const std::vector<std::wstring>& device_names,
                               ScreenCapturer::ScreenList* screens)
{
    DCHECK(screens->empty());

    ScreenCapturer::ScreenList gdi_screens;

    if (!ScreenCaptureUtils::screenList(&gdi_screens))
    {
        LOG(LS_WARNING) << "screenList failed";
        return false;
    }

    ScreenCapturer::ScreenId max_screen_id = -1;

    for (const auto& screen : gdi_screens)
        max_screen_id = std::max(max_screen_id, screen.id);

    for (const auto& device_name : device_names)
    {
        bool device_found = false;

        for (const auto& gdi_screen : gdi_screens)
        {
            std::string device_name_utf8 = utf8FromWide(device_name);

            if (gdi_screen.title == device_name_utf8)
            {
                screens->push_back(gdi_screen);
                device_found = true;

                break;
            }
        }

        if (!device_found)
        {
            // devices_names[i] has not been found in gdi_names, so use max_screen_id.
            ++max_screen_id;
            screens->push_back({ max_screen_id, std::string() });
        }
    }

    return true;
}

int indexFromScreenId(ScreenCapturer::ScreenId id, const std::vector<std::wstring>& device_names)
{
    ScreenCapturer::ScreenList screens;

    if (!screenListFromDeviceNames(device_names, &screens))
    {
        LOG(LS_WARNING) << "screenListFromDeviceNames failed";
        return -1;
    }

    DCHECK_EQ(device_names.size(), screens.size());

    for (size_t i = 0; i < screens.size(); ++i)
    {
        if (screens[i].id == id)
            return static_cast<int>(i);
    }

    LOG(LS_WARNING) << "Screen with ID " << id << " not found";
    return -1;
}

} // namespace

ScreenCapturerDxgi::ScreenCapturerDxgi()
    : ScreenCapturer(Type::WIN_DXGI),
      controller_(std::make_shared<DxgiDuplicatorController>())
{
    LOG(LS_INFO) << "ScreenCapturerDxgi Ctor";
}

ScreenCapturerDxgi::~ScreenCapturerDxgi()
{
    LOG(LS_INFO) << "ScreenCapturerDxgi Dtor";
}

bool ScreenCapturerDxgi::isSupported()
{
    // Forwards isSupported() function call to DxgiDuplicatorController.
    return controller_->isSupported();
}

// static
bool ScreenCapturerDxgi::isCurrentSessionSupported()
{
    return DxgiDuplicatorController::isCurrentSessionSupported();
}

int ScreenCapturerDxgi::screenCount()
{
    return controller_->screenCount();
}

bool ScreenCapturerDxgi::screenList(ScreenList* screens)
{
    std::vector<std::wstring> device_names;

    if (!controller_->deviceNames(&device_names))
    {
        LOG(LS_WARNING) << "deviceNames failed";
        return false;
    }

    return screenListFromDeviceNames(device_names, screens);
}

bool ScreenCapturerDxgi::selectScreen(ScreenId screen_id)
{
    LOG(LS_INFO) << "Select screen with ID: " << screen_id;

    if (screen_id == kFullDesktopScreenId)
    {
        current_screen_id_ = screen_id;
        return true;
    }

    std::vector<std::wstring> device_names;

    if (!controller_->deviceNames(&device_names))
    {
        LOG(LS_WARNING) << "deviceNames failed";
        return false;
    }

    int index = indexFromScreenId(screen_id, device_names);
    if (index == -1)
    {
        LOG(LS_WARNING) << "indexFromScreenId failed";
        return false;
    }

    current_screen_id_ = index;
    return true;
}

const Frame* ScreenCapturerDxgi::captureFrame(Error* error)
{
    DCHECK(error);

    queue_.moveToNextFrame();

    if (!queue_.currentFrame())
    {
        queue_.replaceCurrentFrame(
            std::make_unique<DxgiFrame>(controller_, sharedMemoryFactory()));
    }

    DxgiDuplicatorController::Result result;

    if (current_screen_id_ == kFullDesktopScreenId)
        result = controller_->duplicate(queue_.currentFrame());
    else
        result = controller_->duplicateMonitor(queue_.currentFrame(), current_screen_id_);

    using DuplicateResult = DxgiDuplicatorController::Result;

    if (result != DuplicateResult::SUCCEEDED)
    {
        LOG(LS_ERROR) << "DxgiDuplicatorController failed to capture desktop, error code "
                      << DxgiDuplicatorController::resultName(result);
    }

    switch (result)
    {
        case DuplicateResult::SUCCEEDED:
        {
            *error = Error::SUCCEEDED;
            return queue_.currentFrame()->frame();
        }

        case DuplicateResult::UNSUPPORTED_SESSION:
        {
            LOG(LS_ERROR) << "Current binary is running on a session not supported "
                             "by DirectX screen capturer";
            *error = Error::PERMANENT;
            return nullptr;
        }

        case DuplicateResult::FRAME_PREPARE_FAILED:
        {
            LOG(LS_ERROR) << "Failed to allocate a new Frame";
            // This usually means we do not have enough memory or SharedMemoryFactory cannot work
            // correctly.
            *error = Error::PERMANENT;
            return nullptr;
        }

        case DuplicateResult::INVALID_MONITOR_ID:
        {
            LOG(LS_ERROR) << "Invalid monitor id " << current_screen_id_;
            *error = Error::PERMANENT;
            return nullptr;
        }

        case DuplicateResult::INITIALIZATION_FAILED:
        case DuplicateResult::DUPLICATION_FAILED:
        default:
        {
            *error = Error::TEMPORARY;
            return nullptr;
        }
    }
}

void ScreenCapturerDxgi::reset()
{
    queue_.reset();
}

} // namespace base
<|endoftext|>


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

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbMultiChannelExtractROI.h"
#include "otbStandardFilterWatcher.h"
#include "otbWrapperNumericalParameter.h"
#include "otbWrapperTypes.h"

#include "otbWrapperElevationParametersHandler.h"

#include "otbGenericRSTransform.h"

namespace otb
{
namespace Wrapper
{

class ExtractROI : public Application
{
public:
  /** Standard class typedefs. */
  typedef ExtractROI                          Self;
  typedef Application                         Superclass;
  typedef itk::SmartPointer<Self>             Pointer;
  typedef itk::SmartPointer<const Self>       ConstPointer;

  typedef otb::GenericRSTransform<>           RSTransformType;
  typedef RSTransformType::InputPointType     Point3DType;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ExtractROI, otb::Application);

  /** Filters typedef */
  typedef otb::MultiChannelExtractROI<FloatVectorImageType::InternalPixelType,
                                      FloatVectorImageType::InternalPixelType> ExtractROIFilterType;

private:
  void DoInit()
  {
    SetName("ExtractROI");
    SetDescription("Extract a ROI defined by the user.");

    // Documentation
    SetDocName("Extract ROI");
    SetDocLongDescription("This application extracts a Region Of Interest with user defined size.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag(Tags::Manip);

    AddParameter(ParameterType_InputImage,  "in",   "Input Image");
    SetParameterDescription("in", "Input image.");
    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
    SetParameterDescription("out", "Output image.");

    AddRAMParameter();

    AddParameter(ParameterType_Choice,"mode","Extraction mode");
    AddChoice("mode.standard","Standard");
    SetParameterDescription("mode.standard","In standard mode, extract is done according the coordinates entered by the user");
    AddChoice("mode.fit","Fit");
    SetParameterDescription("mode.fit","In fit mode, extract is made to best fit a reference image.");

    AddParameter(ParameterType_InputImage,"mode.fit.ref","Reference image");
    SetParameterDescription("mode.fit.ref","Reference image to define the ROI");

    // Elevation
    ElevationParametersHandler::AddElevationParameters(this,"mode.fit.elev");

    AddParameter(ParameterType_Int,  "startx", "Start X");
    SetParameterDescription("startx", "ROI start x position.");
    AddParameter(ParameterType_Int,  "starty", "Start Y");
    SetParameterDescription("starty", "ROI start y position.");
    AddParameter(ParameterType_Int,  "sizex",  "Size X");
    SetParameterDescription("sizex","size along x in pixels.");
    AddParameter(ParameterType_Int,  "sizey",  "Size Y");
    SetParameterDescription("sizey","size along y in pixels.");

    // Default values
    SetDefaultParameterInt("startx", 0);
    SetDefaultParameterInt("starty", 0);
    SetDefaultParameterInt("sizex",  0);
    SetDefaultParameterInt("sizey",  0);

    // Channelist Parameters
    AddParameter(ParameterType_ListView,  "cl", "Output Image channels");
    SetParameterDescription("cl","Channels to write in the output image.");

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "VegetationIndex.hd");
    SetDocExampleParameterValue("startx", "40");
    SetDocExampleParameterValue("starty", "250");
    SetDocExampleParameterValue("sizex", "150");
    SetDocExampleParameterValue("sizey", "150");
    SetDocExampleParameterValue("out", "ExtractROI.tif");
  }

  void DoUpdateParameters()
  {
    // Update the sizes only if the user does not defined a size
    if ( HasValue("in") )
      {
      ExtractROIFilterType::InputImageType* inImage = GetParameterImage("in");
      ExtractROIFilterType::InputImageType::RegionType  largestRegion = inImage->GetLargestPossibleRegion();

      if (!HasUserValue("sizex")  && !HasUserValue("sizey") )
        {
        SetParameterInt("sizex", largestRegion.GetSize()[0]);
        SetParameterInt("sizey", largestRegion.GetSize()[1]);
        }

      // Update the values of the channels to be selected
      unsigned int nbComponents = inImage->GetNumberOfComponentsPerPixel();
      ClearChoices("cl");
      for (unsigned int idx = 0; idx < nbComponents; ++idx)
        {
        std::ostringstream key, item;
        key<<"cl.channel"<<idx+1;
        item<<"Channel"<<idx+1;
        AddChoice(key.str(), item.str());
        }

      // Put the limit of the index and the size relative the image
      SetMinimumParameterIntValue("sizex", 0);
      SetMaximumParameterIntValue("sizex", largestRegion.GetSize(0));

      SetMinimumParameterIntValue("sizey", 0);
      SetMaximumParameterIntValue("sizey", largestRegion.GetSize(1));

      SetMinimumParameterIntValue("startx", 0);
      SetMaximumParameterIntValue("startx", largestRegion.GetSize(0));

      SetMinimumParameterIntValue("starty", 0);
      SetMaximumParameterIntValue("starty", largestRegion.GetSize(1));

      // Crop the roi region to be included in the largest possible
      // region
      if(!this->CropRegionOfInterest())
        {
        // Put the index of the ROI to origin and try to crop again
        SetParameterInt("startx", 0);
        SetParameterInt("starty", 0);
        this->CropRegionOfInterest();
        }
      }

    if(GetParameterString("mode")=="fit")
      {
      this->SetParameterRole("startx",Role_Output);
      this->SetParameterRole("starty",Role_Output);
      this->SetParameterRole("sizex",Role_Output);
      this->SetParameterRole("sizey",Role_Output);

      this->DisableParameter("startx");
      this->DisableParameter("starty");
      this->DisableParameter("sizex");
      this->DisableParameter("sizey");

      }
    else if(GetParameterString("mode")=="standard")
      {
      this->SetParameterRole("startx",Role_Input);
      this->SetParameterRole("starty",Role_Input);
      this->SetParameterRole("sizex",Role_Input);
      this->SetParameterRole("sizey",Role_Input);

      this->EnableParameter("startx");
      this->EnableParameter("starty");
      this->EnableParameter("sizex");
      this->EnableParameter("sizey");
      }
  }

  bool CropRegionOfInterest()
  {
    FloatVectorImageType::RegionType region;
    region.SetSize(0,  GetParameterInt("sizex"));
    region.SetSize(1,  GetParameterInt("sizey"));
    region.SetIndex(0, GetParameterInt("startx"));
    region.SetIndex(1, GetParameterInt("starty"));

    if ( HasValue("in") )
      {
        if (region.Crop(GetParameterImage("in")->GetLargestPossibleRegion()))
          {
            SetParameterInt("sizex", region.GetSize(0));
            SetParameterInt("sizey", region.GetSize(1));
            SetParameterInt("startx", region.GetIndex(0));
            SetParameterInt("starty", region.GetIndex(1));
            return true;
          }
      }
    return false;
  }

  void DoExecute()
  {
    ExtractROIFilterType::InputImageType* inImage = GetParameterImage("in");
    inImage->UpdateOutputInformation();

    if(GetParameterString("mode")=="fit")
      {
      // Setup the DEM Handler
      otb::Wrapper::ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(this,"mode.fit.elev");

      FloatVectorImageType::Pointer referencePtr = this->GetParameterImage<FloatVectorImageType>("mode.fit.ref");
      referencePtr->UpdateOutputInformation();

      RSTransformType::Pointer rsTransform = RSTransformType::New();
      rsTransform->SetInputKeywordList(referencePtr->GetImageKeywordlist());
      rsTransform->SetInputProjectionRef(referencePtr->GetProjectionRef());
      rsTransform->SetOutputKeywordList(inImage->GetImageKeywordlist());
      rsTransform->SetOutputProjectionRef(inImage->GetProjectionRef());
      rsTransform->InstanciateTransform();

      FloatVectorImageType::IndexType uli_ref,uri_ref,lli_ref,lri_ref;

      uli_ref = referencePtr->GetLargestPossibleRegion().GetIndex();
      uri_ref = uli_ref;
      uri_ref[0]+=referencePtr->GetLargestPossibleRegion().GetSize()[0];
      lli_ref = uli_ref;
      lli_ref[1]+=referencePtr->GetLargestPossibleRegion().GetSize()[1];
      lri_ref = lli_ref;
      lri_ref[0]+=referencePtr->GetLargestPossibleRegion().GetSize()[0];

      FloatVectorImageType::PointType ulp_ref,urp_ref,llp_ref,lrp_ref;

      referencePtr->TransformIndexToPhysicalPoint(uli_ref,ulp_ref);
      referencePtr->TransformIndexToPhysicalPoint(uri_ref,urp_ref);
      referencePtr->TransformIndexToPhysicalPoint(lli_ref,llp_ref);
      referencePtr->TransformIndexToPhysicalPoint(lri_ref,lrp_ref);

      FloatVectorImageType::PointType ulp_out, urp_out, llp_out,lrp_out;

      ulp_out = rsTransform->TransformPoint(ulp_ref);
      urp_out = rsTransform->TransformPoint(urp_ref);
      llp_out = rsTransform->TransformPoint(llp_ref);
      lrp_out = rsTransform->TransformPoint(lrp_ref);

      FloatVectorImageType::IndexType uli_out, uri_out, lli_out, lri_out;

      inImage->TransformPhysicalPointToIndex(ulp_out,uli_out);
      inImage->TransformPhysicalPointToIndex(urp_out,uri_out);
      inImage->TransformPhysicalPointToIndex(llp_out,lli_out);
      inImage->TransformPhysicalPointToIndex(lrp_out,lri_out);

      FloatVectorImageType::IndexType uli, lri;

      uli[0] = std::min(std::min(uli_out[0],uri_out[0]),std::min(lli_out[0],lri_out[0]));
      uli[1] = std::min(std::min(uli_out[1],uri_out[1]),std::min(lli_out[1],lri_out[1]));

      lri[0] = std::max(std::max(uli_out[0],uri_out[0]),std::max(lli_out[0],lri_out[0]));
      lri[1] = std::max(std::max(uli_out[1],uri_out[1]),std::max(lli_out[1],lri_out[1]));

      SetParameterInt("startx",uli[0]);
      SetParameterInt("starty",uli[1]);
      SetParameterInt("sizex",lri[0]-uli[0]);
      SetParameterInt("sizey",lri[1]-uli[1]);

      this->CropRegionOfInterest();
      }

    m_ExtractROIFilter = ExtractROIFilterType::New();
    m_ExtractROIFilter->SetInput(inImage);
    m_ExtractROIFilter->SetStartX(GetParameterInt("startx"));
    m_ExtractROIFilter->SetStartY(GetParameterInt("starty"));
    m_ExtractROIFilter->SetSizeX(GetParameterInt("sizex"));
    m_ExtractROIFilter->SetSizeY(GetParameterInt("sizey"));

    for (unsigned int idx = 0; idx < GetSelectedItems("cl").size(); ++idx)
      {
      m_ExtractROIFilter->SetChannel(GetSelectedItems("cl")[idx] + 1 );
      }

    SetParameterOutputImage("out", m_ExtractROIFilter->GetOutput());
  }

  ExtractROIFilterType::Pointer   m_ExtractROIFilter;

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ExtractROI)
<commit_msg>DOC: fix comment<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbMultiChannelExtractROI.h"
#include "otbStandardFilterWatcher.h"
#include "otbWrapperNumericalParameter.h"
#include "otbWrapperTypes.h"

#include "otbWrapperElevationParametersHandler.h"

#include "otbGenericRSTransform.h"

namespace otb
{
namespace Wrapper
{

class ExtractROI : public Application
{
public:
  /** Standard class typedefs. */
  typedef ExtractROI                          Self;
  typedef Application                         Superclass;
  typedef itk::SmartPointer<Self>             Pointer;
  typedef itk::SmartPointer<const Self>       ConstPointer;

  typedef otb::GenericRSTransform<>           RSTransformType;
  typedef RSTransformType::InputPointType     Point3DType;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ExtractROI, otb::Application);

  /** Filters typedef */
  typedef otb::MultiChannelExtractROI<FloatVectorImageType::InternalPixelType,
                                      FloatVectorImageType::InternalPixelType> ExtractROIFilterType;

private:
  void DoInit()
  {
    SetName("ExtractROI");
    SetDescription("Extract a ROI defined by the user.");

    // Documentation
    SetDocName("Extract ROI");
    SetDocLongDescription("This application extracts a Region Of Interest with user defined size.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag(Tags::Manip);

    AddParameter(ParameterType_InputImage,  "in",   "Input Image");
    SetParameterDescription("in", "Input image.");
    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
    SetParameterDescription("out", "Output image.");

    AddRAMParameter();

    AddParameter(ParameterType_Choice,"mode","Extraction mode");
    AddChoice("mode.standard","Standard");
    SetParameterDescription("mode.standard","In standard mode, extract is done according the coordinates entered by the user");
    AddChoice("mode.fit","Fit");
    SetParameterDescription("mode.fit","In fit mode, extract is made to best fit a reference image.");

    AddParameter(ParameterType_InputImage,"mode.fit.ref","Reference image");
    SetParameterDescription("mode.fit.ref","Reference image to define the ROI");

    // Elevation
    ElevationParametersHandler::AddElevationParameters(this,"mode.fit.elev");

    AddParameter(ParameterType_Int,  "startx", "Start X");
    SetParameterDescription("startx", "ROI start x position.");
    AddParameter(ParameterType_Int,  "starty", "Start Y");
    SetParameterDescription("starty", "ROI start y position.");
    AddParameter(ParameterType_Int,  "sizex",  "Size X");
    SetParameterDescription("sizex","size along x in pixels.");
    AddParameter(ParameterType_Int,  "sizey",  "Size Y");
    SetParameterDescription("sizey","size along y in pixels.");

    // Default values
    SetDefaultParameterInt("startx", 0);
    SetDefaultParameterInt("starty", 0);
    SetDefaultParameterInt("sizex",  0);
    SetDefaultParameterInt("sizey",  0);

    // Channelist Parameters
    AddParameter(ParameterType_ListView,  "cl", "Output Image channels");
    SetParameterDescription("cl","Channels to write in the output image.");

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "VegetationIndex.hd");
    SetDocExampleParameterValue("startx", "40");
    SetDocExampleParameterValue("starty", "250");
    SetDocExampleParameterValue("sizex", "150");
    SetDocExampleParameterValue("sizey", "150");
    SetDocExampleParameterValue("out", "ExtractROI.tif");
  }

  void DoUpdateParameters()
  {
    // Update the sizes only if the user has not defined a size
    if ( HasValue("in") )
      {
      ExtractROIFilterType::InputImageType* inImage = GetParameterImage("in");
      ExtractROIFilterType::InputImageType::RegionType  largestRegion = inImage->GetLargestPossibleRegion();

      if (!HasUserValue("sizex")  && !HasUserValue("sizey") )
        {
        SetParameterInt("sizex", largestRegion.GetSize()[0]);
        SetParameterInt("sizey", largestRegion.GetSize()[1]);
        }

      // Update the values of the channels to be selected
      unsigned int nbComponents = inImage->GetNumberOfComponentsPerPixel();
      ClearChoices("cl");
      for (unsigned int idx = 0; idx < nbComponents; ++idx)
        {
        std::ostringstream key, item;
        key<<"cl.channel"<<idx+1;
        item<<"Channel"<<idx+1;
        AddChoice(key.str(), item.str());
        }

      // Put the limit of the index and the size relative the image
      SetMinimumParameterIntValue("sizex", 0);
      SetMaximumParameterIntValue("sizex", largestRegion.GetSize(0));

      SetMinimumParameterIntValue("sizey", 0);
      SetMaximumParameterIntValue("sizey", largestRegion.GetSize(1));

      SetMinimumParameterIntValue("startx", 0);
      SetMaximumParameterIntValue("startx", largestRegion.GetSize(0));

      SetMinimumParameterIntValue("starty", 0);
      SetMaximumParameterIntValue("starty", largestRegion.GetSize(1));

      // Crop the roi region to be included in the largest possible
      // region
      if(!this->CropRegionOfInterest())
        {
        // Put the index of the ROI to origin and try to crop again
        SetParameterInt("startx", 0);
        SetParameterInt("starty", 0);
        this->CropRegionOfInterest();
        }
      }

    if(GetParameterString("mode")=="fit")
      {
      this->SetParameterRole("startx",Role_Output);
      this->SetParameterRole("starty",Role_Output);
      this->SetParameterRole("sizex",Role_Output);
      this->SetParameterRole("sizey",Role_Output);

      this->DisableParameter("startx");
      this->DisableParameter("starty");
      this->DisableParameter("sizex");
      this->DisableParameter("sizey");

      }
    else if(GetParameterString("mode")=="standard")
      {
      this->SetParameterRole("startx",Role_Input);
      this->SetParameterRole("starty",Role_Input);
      this->SetParameterRole("sizex",Role_Input);
      this->SetParameterRole("sizey",Role_Input);

      this->EnableParameter("startx");
      this->EnableParameter("starty");
      this->EnableParameter("sizex");
      this->EnableParameter("sizey");
      }
  }

  bool CropRegionOfInterest()
  {
    FloatVectorImageType::RegionType region;
    region.SetSize(0,  GetParameterInt("sizex"));
    region.SetSize(1,  GetParameterInt("sizey"));
    region.SetIndex(0, GetParameterInt("startx"));
    region.SetIndex(1, GetParameterInt("starty"));

    if ( HasValue("in") )
      {
        if (region.Crop(GetParameterImage("in")->GetLargestPossibleRegion()))
          {
            SetParameterInt("sizex", region.GetSize(0));
            SetParameterInt("sizey", region.GetSize(1));
            SetParameterInt("startx", region.GetIndex(0));
            SetParameterInt("starty", region.GetIndex(1));
            return true;
          }
      }
    return false;
  }

  void DoExecute()
  {
    ExtractROIFilterType::InputImageType* inImage = GetParameterImage("in");
    inImage->UpdateOutputInformation();

    if(GetParameterString("mode")=="fit")
      {
      // Setup the DEM Handler
      otb::Wrapper::ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(this,"mode.fit.elev");

      FloatVectorImageType::Pointer referencePtr = this->GetParameterImage<FloatVectorImageType>("mode.fit.ref");
      referencePtr->UpdateOutputInformation();

      RSTransformType::Pointer rsTransform = RSTransformType::New();
      rsTransform->SetInputKeywordList(referencePtr->GetImageKeywordlist());
      rsTransform->SetInputProjectionRef(referencePtr->GetProjectionRef());
      rsTransform->SetOutputKeywordList(inImage->GetImageKeywordlist());
      rsTransform->SetOutputProjectionRef(inImage->GetProjectionRef());
      rsTransform->InstanciateTransform();

      FloatVectorImageType::IndexType uli_ref,uri_ref,lli_ref,lri_ref;

      uli_ref = referencePtr->GetLargestPossibleRegion().GetIndex();
      uri_ref = uli_ref;
      uri_ref[0]+=referencePtr->GetLargestPossibleRegion().GetSize()[0];
      lli_ref = uli_ref;
      lli_ref[1]+=referencePtr->GetLargestPossibleRegion().GetSize()[1];
      lri_ref = lli_ref;
      lri_ref[0]+=referencePtr->GetLargestPossibleRegion().GetSize()[0];

      FloatVectorImageType::PointType ulp_ref,urp_ref,llp_ref,lrp_ref;

      referencePtr->TransformIndexToPhysicalPoint(uli_ref,ulp_ref);
      referencePtr->TransformIndexToPhysicalPoint(uri_ref,urp_ref);
      referencePtr->TransformIndexToPhysicalPoint(lli_ref,llp_ref);
      referencePtr->TransformIndexToPhysicalPoint(lri_ref,lrp_ref);

      FloatVectorImageType::PointType ulp_out, urp_out, llp_out,lrp_out;

      ulp_out = rsTransform->TransformPoint(ulp_ref);
      urp_out = rsTransform->TransformPoint(urp_ref);
      llp_out = rsTransform->TransformPoint(llp_ref);
      lrp_out = rsTransform->TransformPoint(lrp_ref);

      FloatVectorImageType::IndexType uli_out, uri_out, lli_out, lri_out;

      inImage->TransformPhysicalPointToIndex(ulp_out,uli_out);
      inImage->TransformPhysicalPointToIndex(urp_out,uri_out);
      inImage->TransformPhysicalPointToIndex(llp_out,lli_out);
      inImage->TransformPhysicalPointToIndex(lrp_out,lri_out);

      FloatVectorImageType::IndexType uli, lri;

      uli[0] = std::min(std::min(uli_out[0],uri_out[0]),std::min(lli_out[0],lri_out[0]));
      uli[1] = std::min(std::min(uli_out[1],uri_out[1]),std::min(lli_out[1],lri_out[1]));

      lri[0] = std::max(std::max(uli_out[0],uri_out[0]),std::max(lli_out[0],lri_out[0]));
      lri[1] = std::max(std::max(uli_out[1],uri_out[1]),std::max(lli_out[1],lri_out[1]));

      SetParameterInt("startx",uli[0]);
      SetParameterInt("starty",uli[1]);
      SetParameterInt("sizex",lri[0]-uli[0]);
      SetParameterInt("sizey",lri[1]-uli[1]);

      this->CropRegionOfInterest();
      }

    m_ExtractROIFilter = ExtractROIFilterType::New();
    m_ExtractROIFilter->SetInput(inImage);
    m_ExtractROIFilter->SetStartX(GetParameterInt("startx"));
    m_ExtractROIFilter->SetStartY(GetParameterInt("starty"));
    m_ExtractROIFilter->SetSizeX(GetParameterInt("sizex"));
    m_ExtractROIFilter->SetSizeY(GetParameterInt("sizey"));

    for (unsigned int idx = 0; idx < GetSelectedItems("cl").size(); ++idx)
      {
      m_ExtractROIFilter->SetChannel(GetSelectedItems("cl")[idx] + 1 );
      }

    SetParameterOutputImage("out", m_ExtractROIFilter->GetOutput());
  }

  ExtractROIFilterType::Pointer   m_ExtractROIFilter;

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ExtractROI)
<|endoftext|>


<commit_before>/*
    Copyright 2012 Ulrik Mikaelsson <ulrik.mikaelsson@gmail.com>

    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 "randomaccessfile.hpp"

#include <boost/assert.hpp>
#include <boost/filesystem/path.hpp>
#include <fcntl.h>
#include <ios>
#include <sys/stat.h>

RandomAccessFile::RandomAccessFile(const boost::filesystem::path& path, RandomAccessFile::Mode mode)
	: _path(path)
{
        int m;
        switch (mode) {
          case READ: m = O_RDONLY; break;
          case WRITE: m = O_WRONLY; break;
          case READWRITE: m = O_RDWR; break;
        }
	_fd = open(path.c_str(), m);
	if (_fd < 0)
		throw std::ios_base::failure("Failed opening "+path.string());
}

RandomAccessFile::~RandomAccessFile()
{
	if (_fd >= 0)
		close(_fd);
}

uint64_t RandomAccessFile::size() const
{
	struct stat s;
	fstat(_fd, &s);
	return s.st_size;
}

uint RandomAccessFile::blocks(size_t blockSize) const
{
	// Round up the number of blocks
	return (size() + blockSize - 1) / blockSize;
}

byte* RandomAccessFile::read(uint64_t offset, size_t& size, byte* buf)
{
	BOOST_ASSERT( size <= WINDOW_SIZE );
	ssize_t read = pread64(_fd, buf, size, offset);
	if ( read > 0 ) {
		size = read;
		return buf;
	} else {
		size = 0;
		return NULL;
	}
}

ssize_t RandomAccessFile::write(uint64_t offset, void* src, size_t size)
{
	BOOST_ASSERT( size <= WINDOW_SIZE );
	ssize_t written = pwrite64(_fd, src, size, offset);
	BOOST_ASSERT( (size_t)written == size ); // TODO: Real error-handling
	return written;
}

const boost::filesystem3::path& RandomAccessFile::path() const
{
	return _path;
}

<commit_msg>[bithorded/lib/RandomAccessFile]Throw real exception on write-failure.<commit_after>/*
    Copyright 2012 Ulrik Mikaelsson <ulrik.mikaelsson@gmail.com>

    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 "randomaccessfile.hpp"

#include <boost/assert.hpp>
#include <boost/filesystem/path.hpp>
#include <fcntl.h>
#include <ios>
#include <sys/stat.h>

RandomAccessFile::RandomAccessFile(const boost::filesystem::path& path, RandomAccessFile::Mode mode)
	: _path(path)
{
        int m;
        switch (mode) {
          case READ: m = O_RDONLY; break;
          case WRITE: m = O_WRONLY; break;
          case READWRITE: m = O_RDWR; break;
        }
	_fd = open(path.c_str(), m);
	if (_fd < 0)
		throw std::ios_base::failure("Failed opening "+path.string());
}

RandomAccessFile::~RandomAccessFile()
{
	if (_fd >= 0)
		close(_fd);
}

uint64_t RandomAccessFile::size() const
{
	struct stat s;
	fstat(_fd, &s);
	return s.st_size;
}

uint RandomAccessFile::blocks(size_t blockSize) const
{
	// Round up the number of blocks
	return (size() + blockSize - 1) / blockSize;
}

byte* RandomAccessFile::read(uint64_t offset, size_t& size, byte* buf)
{
	BOOST_ASSERT( size <= WINDOW_SIZE );
	ssize_t read = pread64(_fd, buf, size, offset);
	if ( read > 0 ) {
		size = read;
		return buf;
	} else {
		size = 0;
		return NULL;
	}
}

ssize_t RandomAccessFile::write(uint64_t offset, void* src, size_t size)
{
	BOOST_ASSERT( size <= WINDOW_SIZE );
	ssize_t written = pwrite64(_fd, src, size, offset);
	if ((size_t)written != size)
		throw std::ios_base::failure("Failed to write");
	return written;
}

const boost::filesystem3::path& RandomAccessFile::path() const
{
	return _path;
}

<|endoftext|>


<commit_before>/**
 * File: 02_std_containers.cpp
 *
 * Description: Example of automatic test checking, which
 * member functions are defined for various STD containers.
 * A simple report is generated, which is saved in a log file
 * with user-defined filename (default: 02_std_container.log).
 *
 * Author(s): Piotr Kuszaj (2016)
 */

#include <unordered_map> // std::unordered_map
#include <list>          // std::list
#include <string>        // std::string

#include <memory>        // std::unique_ptr
#include <fstream>       // std::ostream
#include <iostream>      // std::cout
#include <iomanip>       // std::setw, std::setfill

#include <SFEC/SFEC.h>   // SFEC_declHasFunctionMemberType

/**
 * Containers
 */
#include <array>
#include <deque>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>

using namespace std;

/**
 * Class for testing container function members.
 */
template <class Container>
class ContainerTest {
    private:
        // Map container with test's results
        unordered_map< string, bool > m_report;

        // List container with map key order
        list< string > m_order;

        // Declaring function member structures used in automatic test
        SFEC_declHasFunctionMemberType(size);       // has_function_member_size
        SFEC_declHasFunctionMemberType(empty);      // has_function_member_empty
        SFEC_declHasFunctionMemberType(push_back);  // has_function_member_push_back
        SFEC_declHasFunctionMemberType(push_front); // has_function_member_push_front
        SFEC_declHasFunctionMemberType(pop_back);   // has_function_member_pop_back
        SFEC_declHasFunctionMemberType(pop_front);  // has_function_member_pop_front
        SFEC_declHasFunctionMemberType(clear);      // has_function_member_clear
        SFEC_declHasFunctionMemberType(swap);       // has_function_member_swap
        SFEC_declHasFunctionMemberType(sort);       // has_function_member_sort
        SFEC_declHasFunctionMemberType(reverse);    // has_function_member_reverse

    public:
        // Default constructor
        ContainerTest();

        // Lshift operator for passing test report to
        // an ostream object.
        template <class _Container>
        friend
        ostream& operator<<(ostream& os,
                            const ContainerTest<_Container>& ct);
};

/**
 * Default constructor
 * Initializes m_report map, which is used in generating function
 * membership report.
 */
template <class Container>
ContainerTest<Container>::ContainerTest() {
    // size
    m_order.push_back("size");
    m_report["size"] =
        has_function_member_size<Container,
                                 typename Container::size_type>::value;

    // empty
    m_order.push_back("empty");
    m_report["empty"] =
        has_function_member_empty<Container,
                                  bool>::value;

    // push_back
    m_order.push_back("push_back");
    m_report["push_back"] =
        has_function_member_push_back<Container,
                                      void,
                                      typename Container::value_type>::value;

    // push_front
    m_order.push_back("push_front");
    m_report["push_front"] =
        has_function_member_push_front<Container,
                                       void,
                                       typename Container::value_type>::value;

    // pop_back
    m_order.push_back("pop_back");
    m_report["pop_back"] =
        has_function_member_pop_back<Container>::value;

    // push_front
    m_order.push_back("pop_front");
    m_report["pop_front"] =
        has_function_member_pop_front<Container>::value;

    // clear
    m_order.push_back("clear");
    m_report["clear"] =
        has_function_member_clear<Container>::value;

    // swap
    m_order.push_back("swap");
    m_report["swap"] =
        has_function_member_swap<Container,
                                 void,
                                 Container&>::value;

    // sort
    m_order.push_back("sort");
    m_report["sort"] =
        has_function_member_sort<Container>::value;

    // reverse
    m_order.push_back("reverse");
    m_report["reverse"] =
        has_function_member_reverse<Container>::value;
}

/**
 * Operator for passing test report to an ostream object
 */
template <class _Container>
ostream&
operator<<(ostream& os,
           const ContainerTest<_Container>& ct) {
    // Print bool value for every map key
    for (auto const & key : ct.m_order) {
        // Formatting
        os << left << setw(15) << setfill(' ');

        // Function mamber name
        os << key;

        // Print if container has defined function
        // member
        if ( ct.m_report.at(key) ) {
            os << "yes";
        } else {
            os << "no";
        }

        os << endl;
    }

    return os;
}

int main (int argc, char **argv) {
    // Report filename
    string reportFilename;
    if (argc > 1) {
        reportFilename = argv[1];
    } else {
        // Default report filename
        reportFilename = "02_std_containers.log";
    }

    // Output file with report data
    ofstream output;
    output.open(reportFilename);

    ////
    // Declaring ContainerTest objects for
    // various std containers
    ////

    // Array
    ContainerTest<array<int,0> > ctArray;
    // Deque
    ContainerTest<deque<int> >   ctDeque;
    // List
    ContainerTest<list<int> >    ctList;
    // Map
    ContainerTest<map<int,int> > ctMap;
    // Queue
    ContainerTest<queue<int> >   ctQueue;
    // Set
    ContainerTest<set<int> >     ctSet;
    // Stack
    ContainerTest<stack<int> >   ctStack;
    // Vector
    ContainerTest<vector<int> >  ctVector;

    // Saving reports in output file
    output << "== Array =="  << endl << ctArray  << endl;
    output << "== Deque =="  << endl << ctDeque  << endl;
    output << "== List =="   << endl << ctList   << endl;
    output << "== Map =="    << endl << ctMap    << endl;
    output << "== Queue =="  << endl << ctQueue  << endl;
    output << "== Set =="    << endl << ctSet    << endl;
    output << "== Stack =="  << endl << ctStack  << endl;
    output << "== Vector ==" << endl << ctVector << endl;

    cout << "Saved in " << reportFilename << endl;

    return 0;
}
<commit_msg>Preamble correction<commit_after>/**
 * File: 02_std_containers.cpp
 *
 * Description: Example of automatic test checking, which
 * member functions are defined for various STD containers.
 * A simple report is generated, which is saved in a log file
 * with filename passed as executable's first argument. If no
 * filename is provided, program will save report in
 * '02_std_container.log' file.
 *
 * Author(s): Piotr Kuszaj (2016)
 */

#include <unordered_map> // std::unordered_map
#include <list>          // std::list
#include <string>        // std::string

#include <memory>        // std::unique_ptr
#include <fstream>       // std::ostream
#include <iostream>      // std::cout
#include <iomanip>       // std::setw, std::setfill

#include <SFEC/SFEC.h>   // SFEC_declHasFunctionMemberType

/**
 * Containers
 */
#include <array>
#include <deque>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>

using namespace std;

/**
 * Class for testing container function members.
 */
template <class Container>
class ContainerTest {
    private:
        // Map container with test's results
        unordered_map< string, bool > m_report;

        // List container with map key order
        list< string > m_order;

        // Declaring function member structures used in automatic test
        SFEC_declHasFunctionMemberType(size);       // has_function_member_size
        SFEC_declHasFunctionMemberType(empty);      // has_function_member_empty
        SFEC_declHasFunctionMemberType(push_back);  // has_function_member_push_back
        SFEC_declHasFunctionMemberType(push_front); // has_function_member_push_front
        SFEC_declHasFunctionMemberType(pop_back);   // has_function_member_pop_back
        SFEC_declHasFunctionMemberType(pop_front);  // has_function_member_pop_front
        SFEC_declHasFunctionMemberType(clear);      // has_function_member_clear
        SFEC_declHasFunctionMemberType(swap);       // has_function_member_swap
        SFEC_declHasFunctionMemberType(sort);       // has_function_member_sort
        SFEC_declHasFunctionMemberType(reverse);    // has_function_member_reverse

    public:
        // Default constructor
        ContainerTest();

        // Lshift operator for passing test report to
        // an ostream object.
        template <class _Container>
        friend
        ostream& operator<<(ostream& os,
                            const ContainerTest<_Container>& ct);
};

/**
 * Default constructor
 * Initializes m_report map, which is used in generating function
 * membership report.
 */
template <class Container>
ContainerTest<Container>::ContainerTest() {
    // size
    m_order.push_back("size");
    m_report["size"] =
        has_function_member_size<Container,
                                 typename Container::size_type>::value;

    // empty
    m_order.push_back("empty");
    m_report["empty"] =
        has_function_member_empty<Container,
                                  bool>::value;

    // push_back
    m_order.push_back("push_back");
    m_report["push_back"] =
        has_function_member_push_back<Container,
                                      void,
                                      typename Container::value_type>::value;

    // push_front
    m_order.push_back("push_front");
    m_report["push_front"] =
        has_function_member_push_front<Container,
                                       void,
                                       typename Container::value_type>::value;

    // pop_back
    m_order.push_back("pop_back");
    m_report["pop_back"] =
        has_function_member_pop_back<Container>::value;

    // push_front
    m_order.push_back("pop_front");
    m_report["pop_front"] =
        has_function_member_pop_front<Container>::value;

    // clear
    m_order.push_back("clear");
    m_report["clear"] =
        has_function_member_clear<Container>::value;

    // swap
    m_order.push_back("swap");
    m_report["swap"] =
        has_function_member_swap<Container,
                                 void,
                                 Container&>::value;

    // sort
    m_order.push_back("sort");
    m_report["sort"] =
        has_function_member_sort<Container>::value;

    // reverse
    m_order.push_back("reverse");
    m_report["reverse"] =
        has_function_member_reverse<Container>::value;
}

/**
 * Operator for passing test report to an ostream object
 */
template <class _Container>
ostream&
operator<<(ostream& os,
           const ContainerTest<_Container>& ct) {
    // Print bool value for every map key
    for (auto const & key : ct.m_order) {
        // Formatting
        os << left << setw(15) << setfill(' ');

        // Function mamber name
        os << key;

        // Print if container has defined function
        // member
        if ( ct.m_report.at(key) ) {
            os << "yes";
        } else {
            os << "no";
        }

        os << endl;
    }

    return os;
}

int main (int argc, char **argv) {
    // Report filename
    string reportFilename;
    if (argc > 1) {
        reportFilename = argv[1];
    } else {
        // Default report filename
        reportFilename = "02_std_containers.log";
    }

    // Output file with report data
    ofstream output;
    output.open(reportFilename);

    ////
    // Declaring ContainerTest objects for
    // various std containers
    ////

    // Array
    ContainerTest<array<int,0> > ctArray;
    // Deque
    ContainerTest<deque<int> >   ctDeque;
    // List
    ContainerTest<list<int> >    ctList;
    // Map
    ContainerTest<map<int,int> > ctMap;
    // Queue
    ContainerTest<queue<int> >   ctQueue;
    // Set
    ContainerTest<set<int> >     ctSet;
    // Stack
    ContainerTest<stack<int> >   ctStack;
    // Vector
    ContainerTest<vector<int> >  ctVector;

    // Saving reports in output file
    output << "== Array =="  << endl << ctArray  << endl;
    output << "== Deque =="  << endl << ctDeque  << endl;
    output << "== List =="   << endl << ctList   << endl;
    output << "== Map =="    << endl << ctMap    << endl;
    output << "== Queue =="  << endl << ctQueue  << endl;
    output << "== Set =="    << endl << ctSet    << endl;
    output << "== Stack =="  << endl << ctStack  << endl;
    output << "== Vector ==" << endl << ctVector << endl;

    cout << "Saved in " << reportFilename << endl;

    return 0;
}
<|endoftext|>


<commit_before>#include "steam_controller.h"

device_plugin scdev;

int sc_plugin_init(plugin_api api) {
  //set static vars
  steam_controller_manager::methods = *(api.head.manager);
  steam_controller::methods = *(api.head.device);
  steam_controller_manager* manager = new steam_controller_manager();

  //set manager call backs
  manager_plugin scman;
  memset(&scman, 0, sizeof(scman));
  scman.size = sizeof(scman);
  scman.name = "steamcontroller";
  scman.subscribe_to_gamepad_profile = true;
  scman.init = [] (void* plug_data, device_manager* ref) -> int {
    return ((steam_controller_manager*)plug_data)->init(ref);
  };
  scman.destroy = [] (void* data) -> int {
    delete (steam_controller_manager*) data;
    return 0;
  };
  scman.start = [] (void* data) {
    return ((steam_controller_manager*)data)->start();
  };
  scman.process_manager_option = nullptr;
  scman.process_udev_event = [] (void* data, struct udev* udev, struct udev_device* dev) {
    return -1; //This driver doesn't use udev events!
  };

  //set device call backs
  memset(&scdev, 0, sizeof(scdev));
  scdev.size = sizeof(scdev);
  scdev.name_stem = "sc";
  scdev.uniq = "";
  scdev.phys = "";
  scdev.init = [] (void* data, input_source* ref) -> int {
    steam_controller* sc = ((steam_controller*)data);
    sc->ref = ref;
    steam_controller::methods.watch_file(ref, sc->statepipe[0], sc->statepipe);
    return 0;
  };
  scdev.destroy = [] (void* data) -> int {
    delete (steam_controller*) data;
    return 0;
  };
  scdev.get_description = [] (const void* data) {
    return "Steam Controller";
  };
  scdev.get_type = [] (const void* data) {
    return "gamepad";
  };
  scdev.process_event = [] (void* data, void* tag) -> int {
    ((steam_controller*)data)->process(tag);
    return 0;
  };
  scdev.process_option = [] (void* data, const char* opname, MGField opvalue) {
    return ((steam_controller*)data)->process_option(opname, opvalue);
  };
  scdev.upload_ff = nullptr;
  scdev.erase_ff = nullptr;
  scdev.play_ff = nullptr;

  api.mg.add_manager(scman,  manager);
  return 0;
}

int sc_loaded = register_plugin(&sc_plugin_init);
<commit_msg>fix sc plugin missing memset def<commit_after>#include "steam_controller.h"
#include <cstring>

device_plugin scdev;

int sc_plugin_init(plugin_api api) {
  //set static vars
  steam_controller_manager::methods = *(api.head.manager);
  steam_controller::methods = *(api.head.device);
  steam_controller_manager* manager = new steam_controller_manager();

  //set manager call backs
  manager_plugin scman;
  memset(&scman, 0, sizeof(scman));
  scman.size = sizeof(scman);
  scman.name = "steamcontroller";
  scman.subscribe_to_gamepad_profile = true;
  scman.init = [] (void* plug_data, device_manager* ref) -> int {
    return ((steam_controller_manager*)plug_data)->init(ref);
  };
  scman.destroy = [] (void* data) -> int {
    delete (steam_controller_manager*) data;
    return 0;
  };
  scman.start = [] (void* data) {
    return ((steam_controller_manager*)data)->start();
  };
  scman.process_manager_option = nullptr;
  scman.process_udev_event = [] (void* data, struct udev* udev, struct udev_device* dev) {
    return -1; //This driver doesn't use udev events!
  };

  //set device call backs
  memset(&scdev, 0, sizeof(scdev));
  scdev.size = sizeof(scdev);
  scdev.name_stem = "sc";
  scdev.uniq = "";
  scdev.phys = "";
  scdev.init = [] (void* data, input_source* ref) -> int {
    steam_controller* sc = ((steam_controller*)data);
    sc->ref = ref;
    steam_controller::methods.watch_file(ref, sc->statepipe[0], sc->statepipe);
    return 0;
  };
  scdev.destroy = [] (void* data) -> int {
    delete (steam_controller*) data;
    return 0;
  };
  scdev.get_description = [] (const void* data) {
    return "Steam Controller";
  };
  scdev.get_type = [] (const void* data) {
    return "gamepad";
  };
  scdev.process_event = [] (void* data, void* tag) -> int {
    ((steam_controller*)data)->process(tag);
    return 0;
  };
  scdev.process_option = [] (void* data, const char* opname, MGField opvalue) {
    return ((steam_controller*)data)->process_option(opname, opvalue);
  };
  scdev.upload_ff = nullptr;
  scdev.erase_ff = nullptr;
  scdev.play_ff = nullptr;

  api.mg.add_manager(scman,  manager);
  return 0;
}

int sc_loaded = register_plugin(&sc_plugin_init);
<|endoftext|>


<commit_before>#ifndef CLIENT_HPP
#define CLIENT_HPP

#include <Cpp/Events.hpp>

class ISomeInterface
{
protected:
	ISomeInterface() {}
	~ISomeInterface() {}
public:
	virtual Cpp::EventRef<bool> testEvent1() = 0;
};

class BaseClass
{
public:
	BaseClass() {}
	virtual ~BaseClass() {}

	virtual Cpp::EventRef<int> testEvent2() { return testEvent2_ ; }

	void fireEvent2(int x) { testEvent2_.fire(x); }
private:
	Cpp::Event<int> testEvent2_;
};

class DerivedClass : public BaseClass, public ISomeInterface
{
public:
	DerivedClass()
		: BaseClass()
	{
		scope_.connectEvent(BaseClass::testEvent2(), &testEvent2x_);
		scope_.connectEvent(BaseClass::testEvent2(), &eventEx_, 3.14);
	}
	~DerivedClass() {}

	virtual Cpp::EventRef<int> testEvent2() { return testEvent2x_ ; }
	virtual Cpp::EventRef<bool> testEvent1() { return testEvent1_ ; }
private:
	Cpp::Event<bool> testEvent1_;
	Cpp::Event<int> testEvent2x_;
	Cpp::Event<double, int> eventEx_;
	Cpp::ConnectionScope scope_;
};

class Server;

#pragma pack(push, 16)

class Client
{
public:
	Client();
	~Client();

	Server * server() const { return server_; }
	void setServer(Server * serv);

	void test();

	void registerData(Server * server);

	Cpp::ConnectionScope * tracker() { return &scope_; }
private:
	Server * server_;
	Cpp::ConnectionScope scope_;

	void processData(float x);
};

#pragma pack(pop)

#endif //CLIENT_HPP<commit_msg>*: #pragma pack removed from EventsDemo/Client.hpp<commit_after>#ifndef CLIENT_HPP
#define CLIENT_HPP

#include <Cpp/Events.hpp>

class ISomeInterface
{
protected:
	ISomeInterface() {}
	~ISomeInterface() {}
public:
	virtual Cpp::EventRef<bool> testEvent1() = 0;
};

class BaseClass
{
public:
	BaseClass() {}
	virtual ~BaseClass() {}

	virtual Cpp::EventRef<int> testEvent2() { return testEvent2_ ; }

	void fireEvent2(int x) { testEvent2_.fire(x); }
private:
	Cpp::Event<int> testEvent2_;
};

class DerivedClass : public BaseClass, public ISomeInterface
{
public:
	DerivedClass()
		: BaseClass()
	{
		scope_.connectEvent(BaseClass::testEvent2(), &testEvent2x_);
		scope_.connectEvent(BaseClass::testEvent2(), &eventEx_, 3.14);
	}
	~DerivedClass() {}

	virtual Cpp::EventRef<int> testEvent2() { return testEvent2x_ ; }
	virtual Cpp::EventRef<bool> testEvent1() { return testEvent1_ ; }
private:
	Cpp::Event<bool> testEvent1_;
	Cpp::Event<int> testEvent2x_;
	Cpp::Event<double, int> eventEx_;
	Cpp::ConnectionScope scope_;
};

class Server;

class Client
{
public:
	Client();
	~Client();

	Server * server() const { return server_; }
	void setServer(Server * serv);

	void test();

	void registerData(Server * server);

	Cpp::ConnectionScope * tracker() { return &scope_; }
private:
	Server * server_;
	Cpp::ConnectionScope scope_;

	void processData(float x);
};

#endif //CLIENT_HPP<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium team:
http://bohrium.bitbucket.org

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium 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 General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

#include <bh_view.hpp>
#include <bh_main_memory.hpp>
#include <memory>

namespace bhxx {

/** The base underlying (multiple) arrays */
class BhBase : public bh_base {
public:
    /** Is the memory managed referenced by bh_base's data pointer
     *  managed by Bohrium or is it owned externally
     *
     * \note If this flag is false, the class will make sure that
     *       the memory is not deleted when going out of scope.
     *  */
    bool ownMemory() {
        return m_own_memory;
    }

    /** Construct a base array with nelem elements using
     * externally managed storage.
     *
     * The class will make sure, that the storage is not deleted when
     * going out of scope.
     *
     * Needless to say that the memory should be large enough to
     * incorporate nelem_ elements.
     * */
    template <typename T>
    BhBase(size_t nelem, T* memory) : bh_base(nelem, bh_type_from_template<T>()), m_own_memory(false) {}

    /** Construct a base array and initialise it with the elements
     *  provided by an iterator range.
     *
     *  The values are copied into the Bohrium storage. If you want to
     *  provide external storage to Bohrium use the constructor
     *  BhBase(size_t nelem, T* memory) instead.
     */
    template <typename InputIterator, typename T = typename std::iterator_traits<InputIterator>::value_type>
    BhBase(InputIterator begin, InputIterator end) : BhBase(T(0), static_cast<size_t>(std::distance(begin, end))) {
        assert(std::distance(begin, end) > 0);

        // Allocate an array and copy the data over.
        bh_data_malloc(this);
        std::copy(begin, end, static_cast<T *>(getDataPtr()));
    }

    /** Construct a base array with nelem elements
     *
     * \param dummy   Dummy argument to fix the type of elements used.
     *                It may only have ever have the value 0 in the
     *                appropriate type.
     *
     * \note The use of this particular constructor is discouraged.
     *       It is only needed from BhArray to construct base objects
     *       which are uninitialised and do not yet hold any deta.
     *       If you wish to construct an uninitialised BhBase object,
     *       do this via the BhArray interface and not using this constructor.
     */
    template <typename T>
    BhBase(T dummy, size_t nelem) : bh_base(nelem, bh_type_from_template<T>()), m_own_memory(true) {

        // The dummy is a dummy argument and should always be identical zero.
        assert(dummy == T(0));
    }

    ~BhBase() {
        // All memory here should be handed over to the Runtime
        // by a BH_FREE instruction and hence no BhBase object
        // should ever point to any memory on deletion
        assert(getDataPtr() == nullptr);
    }

    /** Deleted copy constructor */
    BhBase(const BhBase&) = delete;

    /** Deleted copy assignment */
    BhBase& operator=(const BhBase&) = delete;

    /** Delete move assignment */
    BhBase& operator=(BhBase&& other) = delete;
    // The reason for deleting move and copy is that there might still be
    // objects in the instruction queue which refer to the data
    // pointer used in this object. We hence cannot free the data,
    // but this is our only pointer to it within reach, so we
    // would theoretically need to free it here.

    /** Move another BhBase object here */
    BhBase(BhBase&& other) noexcept :
        bh_base(std::move(other)),
        m_own_memory(other.m_own_memory) {
        other.m_own_memory = true;
        other.resetDataPtr();
    }

private:

    // Is the memory in here owned by Bohrium or is it provided
    // by external means. If it is owned by Bohrium, we assume
    // that Bohrium has also allocated it, which means that if
    // someone is to extract this memory, then he will also
    // need to do the allocation using Bohrium's free function.
    //
    // This is assumed in the release_data() function and this is
    // why this filed is private.
    //
    // Also the BhBaseDeleter might stop working in quirky ways
    // if this flag is allowed to change randomly.
    bool m_own_memory;
};
}
<commit_msg>Fixed `BhBase(size_t nelem, T *memory)`, which ignored `memory`<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium team:
http://bohrium.bitbucket.org

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium 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 General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

#include <bh_view.hpp>
#include <bh_main_memory.hpp>
#include <memory>

namespace bhxx {

/** The base underlying (multiple) arrays */
class BhBase : public bh_base {
public:
    /** Is the memory managed referenced by bh_base's data pointer
     *  managed by Bohrium or is it owned externally
     *
     * \note If this flag is false, the class will make sure that
     *       the memory is not deleted when going out of scope.
     *  */
    bool ownMemory() {
        return m_own_memory;
    }

    /** Construct a base array with nelem elements using
     * externally managed storage.
     *
     * The class will make sure, that the storage is not deleted when
     * going out of scope.
     *
     * Needless to say that the memory should be large enough to
     * incorporate nelem_ elements.
     * */

    template<typename T>
    BhBase(size_t nelem, T *memory) : bh_base(nelem, bh_type_from_template<T>(), memory), m_own_memory(false) {}

    /** Construct a base array and initialise it with the elements
     *  provided by an iterator range.
     *
     *  The values are copied into the Bohrium storage. If you want to
     *  provide external storage to Bohrium use the constructor
     *  BhBase(size_t nelem, T* memory) instead.
     */
    template <typename InputIterator, typename T = typename std::iterator_traits<InputIterator>::value_type>
    BhBase(InputIterator begin, InputIterator end) : BhBase(T(0), static_cast<size_t>(std::distance(begin, end))) {
        assert(std::distance(begin, end) > 0);

        // Allocate an array and copy the data over.
        bh_data_malloc(this);
        std::copy(begin, end, static_cast<T *>(getDataPtr()));
    }

    /** Construct a base array with nelem elements
     *
     * \param dummy   Dummy argument to fix the type of elements used.
     *                It may only have ever have the value 0 in the
     *                appropriate type.
     *
     * \note The use of this particular constructor is discouraged.
     *       It is only needed from BhArray to construct base objects
     *       which are uninitialised and do not yet hold any deta.
     *       If you wish to construct an uninitialised BhBase object,
     *       do this via the BhArray interface and not using this constructor.
     */
    template <typename T>
    BhBase(T dummy, size_t nelem) : bh_base(nelem, bh_type_from_template<T>()), m_own_memory(true) {

        // The dummy is a dummy argument and should always be identical zero.
        assert(dummy == T(0));
    }

    ~BhBase() {
        // All memory here should be handed over to the Runtime
        // by a BH_FREE instruction and hence no BhBase object
        // should ever point to any memory on deletion
        assert(getDataPtr() == nullptr);
    }

    /** Deleted copy constructor */
    BhBase(const BhBase&) = delete;

    /** Deleted copy assignment */
    BhBase& operator=(const BhBase&) = delete;

    /** Delete move assignment */
    BhBase& operator=(BhBase&& other) = delete;
    // The reason for deleting move and copy is that there might still be
    // objects in the instruction queue which refer to the data
    // pointer used in this object. We hence cannot free the data,
    // but this is our only pointer to it within reach, so we
    // would theoretically need to free it here.

    /** Move another BhBase object here */
    BhBase(BhBase&& other) noexcept :
        bh_base(std::move(other)),
        m_own_memory(other.m_own_memory) {
        other.m_own_memory = true;
        other.resetDataPtr();
    }

private:

    // Is the memory in here owned by Bohrium or is it provided
    // by external means. If it is owned by Bohrium, we assume
    // that Bohrium has also allocated it, which means that if
    // someone is to extract this memory, then he will also
    // need to do the allocation using Bohrium's free function.
    //
    // This is assumed in the release_data() function and this is
    // why this filed is private.
    //
    // Also the BhBaseDeleter might stop working in quirky ways
    // if this flag is allowed to change randomly.
    bool m_own_memory;
};
}
<|endoftext|>