<commit_before>// --------------------------------------------------------------------------------------------------
//  Copyright (c) 2016 Microsoft Corporation
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
//  associated documentation files (the "Software"), to deal in the Software without restriction,
//  including without limitation the rights to use, copy, modify, merge, publish, distribute,
//  sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in all copies or
//  substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
//  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
//  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// --------------------------------------------------------------------------------------------------

// Local:
#include "MissionRecord.h"

// Boost:
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

// STL:
#include <exception>
#include <iostream>

namespace malmo
{
    MissionRecord::MissionRecord(const MissionRecordSpec& spec) : spec(spec)
    {
        if (spec.isRecording()) {
            boost::uuids::random_generator gen;
            boost::uuids::uuid temp_uuid = gen();
            char *malmo_tmp_path = getenv("MALMO_TEMP_PATH");
            if (malmo_tmp_path)
                this->temp_dir = boost::filesystem::path(malmo_tmp_path);
            else
                this->temp_dir = boost::filesystem::path(".");
            this->temp_dir = this->temp_dir / "mission_records" / boost::uuids::to_string(temp_uuid);
            this->mp4_path = (this->temp_dir / "video.mp4").string();
            this->observations_path = (this->temp_dir / "observations.txt").string();
            this->rewards_path = (this->temp_dir / "rewards.txt").string();
            this->commands_path = (this->temp_dir / "commands.txt").string();
            this->mission_init_path = (this->temp_dir / "missionInit.xml").string();
            if (boost::filesystem::create_directories(this->temp_dir)) {
                this->is_closed = false;
            }
            else {
                throw std::runtime_error("Could not create temporary folder for recording - trying to write to " + this->temp_dir.string() + " - do you need to change your MALMO_TEMP_PATH environment variable?");
            }
        }
    }

    MissionRecord::~MissionRecord()
    {
        try {
            if (!this->is_closed) {
                this->close();
            }

        }
        catch (const std::exception& e) {
            // we don't really want to assume that is safe to write to cout but can't have destructors throwing exceptions
            std::cout << "Exception in closing of MissionRecord: " << e.what() << std::endl;
        }
        catch(...) {
            // we don't really want to assume that is safe to write to cout but can't have destructors throwing exceptions
            std::cout << "Unknown exception in closing of MissionRecord." << std::endl;
        }
    }

    MissionRecord::MissionRecord(MissionRecord&& record)
        : is_closed(record.is_closed)
        , spec(record.spec)
        , commands_path(record.commands_path)
        , mp4_path(record.mp4_path)
        , observations_path(record.observations_path)
        , rewards_path(record.rewards_path)
        , mission_init_path(record.mission_init_path)
        , temp_dir(record.temp_dir)
    {
        record.spec = MissionRecordSpec();
    }

    MissionRecord& MissionRecord::operator=(MissionRecord&& record)
    {
        if (this != &record){
            this->is_closed = record.is_closed;
            this->spec = record.spec;
            this->commands_path = record.commands_path;
            this->mp4_path = record.mp4_path;
            this->observations_path = record.observations_path;
            this->rewards_path = record.rewards_path;
            this->mission_init_path = record.mission_init_path;
            this->temp_dir = record.temp_dir;

            record.spec = MissionRecordSpec();
        }

        return *this;
    }

    void MissionRecord::close()
    {
        if (!this->spec.isRecording() || this->is_closed){
            return;
        }

        // create zip file, push to destination
        std::vector<boost::filesystem::path> fileList;
        this->addFiles(fileList, this->temp_dir);

        if (fileList.size() > 0){
            std::stringstream out("tempfile");
            lindenb::io::Tar tarball(out);

            for (auto file : fileList){
                try{
                    this->addFile(tarball, file);
                }
                catch (const std::exception& e){
                    std::cout << "[warning] Unable to archive " << file.string() << ": " << e.what() << std::endl;
                }
            }

            tarball.finish();
            {
                std::ofstream file(this->spec.destination, std::ofstream::binary);
                if (file.fail()) {
                    std::cout << "[warning] Unable to write recording to output file " << this->spec.destination << std::endl;
                }
                else {
                    boost::iostreams::filtering_streambuf< boost::iostreams::input> in;
                    in.push(boost::iostreams::gzip_compressor());
                    in.push(out);
                    boost::iostreams::copy(in, file);
                }
            }
        }

        boost::filesystem::remove_all(this->temp_dir);

        this->is_closed = true;
    }

    void MissionRecord::addFiles(std::vector<boost::filesystem::path> &fileList, boost::filesystem::path directory)
    {
        if (!boost::filesystem::exists(directory))
        {
            throw std::runtime_error("Attempt to write to non-existent directory: " + directory.string());
        }
        boost::filesystem::directory_iterator dirIter(directory);
        boost::filesystem::directory_iterator dirIterEnd;

        while (dirIter != dirIterEnd)
        {
            if (boost::filesystem::exists(*dirIter))
            {
                if (boost::filesystem::is_directory(*dirIter)){
                    this->addFiles(fileList, *dirIter);
                }
                else
                {
                    fileList.push_back((*dirIter));
                }
            }

            ++dirIter;
        }
    }

    void MissionRecord::addFile(lindenb::io::Tar& archive, boost::filesystem::path path)
    {
        std::string file_name_in_archive = path.relative_path().normalize().string();
        std::replace(file_name_in_archive.begin(), file_name_in_archive.end(), '\\', '/');
        file_name_in_archive = file_name_in_archive.substr(2, file_name_in_archive.size());
        archive.putFile(path.string().c_str(), file_name_in_archive.c_str());
    }

    bool MissionRecord::isRecording() const
    {
        return this->spec.isRecording();
    }

    bool MissionRecord::isRecordingMP4() const
    {
        return this->spec.is_recording_mp4;
    }

    bool MissionRecord::isRecordingObservations() const
    {
        return this->spec.is_recording_observations;
    }

    bool MissionRecord::isRecordingRewards() const
    {
        return this->spec.is_recording_rewards;
    }

    bool MissionRecord::isRecordingCommands() const
    {
        return this->spec.is_recording_commands;
    }

    std::string MissionRecord::getMP4Path() const
    {
        return this->mp4_path;
    }

    int64_t MissionRecord::getMP4BitRate() const
    {
        return this->spec.mp4_bit_rate;
    }

    int MissionRecord::getMP4FramesPerSecond() const
    {
        return this->spec.mp4_fps;
    }

    std::string MissionRecord::getObservationsPath() const
    {
        return this->observations_path;
    }

    std::string MissionRecord::getRewardsPath() const
    {
        return this->rewards_path;
    }

    std::string MissionRecord::getCommandsPath() const
    {
        return this->commands_path;
    }

    std::string MissionRecord::getMissionInitPath() const
    {
        return this->mission_init_path;
    }

    std::string MissionRecord::getTemporaryDirectory() const
    {
        if (!this->spec.isRecording()){
            throw std::runtime_error("Mission is not being recorded.");
        }

        if (boost::filesystem::exists(this->temp_dir)){
            return this->temp_dir.string();
        }
        else{
            throw std::runtime_error("Mission record does not yet exist. Temporary directory will be created once a mission has begun.");
        }
    }
}
<commit_msg>Now handles failure when creating temp recording folder.<commit_after>// --------------------------------------------------------------------------------------------------
//  Copyright (c) 2016 Microsoft Corporation
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
//  associated documentation files (the "Software"), to deal in the Software without restriction,
//  including without limitation the rights to use, copy, modify, merge, publish, distribute,
//  sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in all copies or
//  substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
//  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
//  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// --------------------------------------------------------------------------------------------------

// Local:
#include "MissionRecord.h"

// Boost:
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

// STL:
#include <exception>
#include <iostream>

namespace malmo
{
    MissionRecord::MissionRecord(const MissionRecordSpec& spec) : spec(spec)
    {
        if (spec.isRecording()) {
            boost::uuids::random_generator gen;
            boost::uuids::uuid temp_uuid = gen();
            char *malmo_tmp_path = getenv("MALMO_TEMP_PATH");
            if (malmo_tmp_path)
                this->temp_dir = boost::filesystem::path(malmo_tmp_path);
            else
                this->temp_dir = boost::filesystem::path(".");
            this->temp_dir = this->temp_dir / "mission_records" / boost::uuids::to_string(temp_uuid);
            this->mp4_path = (this->temp_dir / "video.mp4").string();
            this->observations_path = (this->temp_dir / "observations.txt").string();
            this->rewards_path = (this->temp_dir / "rewards.txt").string();
            this->commands_path = (this->temp_dir / "commands.txt").string();
            this->mission_init_path = (this->temp_dir / "missionInit.xml").string();
            bool created_tmp = false;
            try {
                created_tmp = boost::filesystem::create_directories(this->temp_dir);
            }
            catch (const std::exception& e) {
                std::cout << "Unable to create temporary folder for recording " << this->temp_dir.string() << ": " << e.what() << std::endl;
                throw std::runtime_error("Check your MALMO_TEMP_PATH and try again.");
            }

            if (created_tmp) {
                this->is_closed = false;
            }
            else {
                throw std::runtime_error("Unable to create temporary folder for recording " + this->temp_dir.string() + ": check your MALMO_TEMP_PATH?");
            }
        }
    }

    MissionRecord::~MissionRecord()
    {
        try {
            if (!this->is_closed) {
                this->close();
            }

        }
        catch (const std::exception& e) {
            // we don't really want to assume that is safe to write to cout but can't have destructors throwing exceptions
            std::cout << "Exception in closing of MissionRecord: " << e.what() << std::endl;
        }
        catch(...) {
            // we don't really want to assume that is safe to write to cout but can't have destructors throwing exceptions
            std::cout << "Unknown exception in closing of MissionRecord." << std::endl;
        }
    }

    MissionRecord::MissionRecord(MissionRecord&& record)
        : is_closed(record.is_closed)
        , spec(record.spec)
        , commands_path(record.commands_path)
        , mp4_path(record.mp4_path)
        , observations_path(record.observations_path)
        , rewards_path(record.rewards_path)
        , mission_init_path(record.mission_init_path)
        , temp_dir(record.temp_dir)
    {
        record.spec = MissionRecordSpec();
    }

    MissionRecord& MissionRecord::operator=(MissionRecord&& record)
    {
        if (this != &record){
            this->is_closed = record.is_closed;
            this->spec = record.spec;
            this->commands_path = record.commands_path;
            this->mp4_path = record.mp4_path;
            this->observations_path = record.observations_path;
            this->rewards_path = record.rewards_path;
            this->mission_init_path = record.mission_init_path;
            this->temp_dir = record.temp_dir;

            record.spec = MissionRecordSpec();
        }

        return *this;
    }

    void MissionRecord::close()
    {
        if (!this->spec.isRecording() || this->is_closed){
            return;
        }

        // create zip file, push to destination
        std::vector<boost::filesystem::path> fileList;
        this->addFiles(fileList, this->temp_dir);

        if (fileList.size() > 0){
            std::stringstream out("tempfile");
            lindenb::io::Tar tarball(out);

            for (auto file : fileList){
                try{
                    this->addFile(tarball, file);
                }
                catch (const std::exception& e){
                    std::cout << "[warning] Unable to archive " << file.string() << ": " << e.what() << std::endl;
                }
            }

            tarball.finish();
            {
                std::ofstream file(this->spec.destination, std::ofstream::binary);
                if (file.fail()) {
                    std::cout << "[warning] Unable to write recording to output file " << this->spec.destination << std::endl;
                }
                else {
                    boost::iostreams::filtering_streambuf< boost::iostreams::input> in;
                    in.push(boost::iostreams::gzip_compressor());
                    in.push(out);
                    boost::iostreams::copy(in, file);
                }
            }
        }

        boost::filesystem::remove_all(this->temp_dir);

        this->is_closed = true;
    }

    void MissionRecord::addFiles(std::vector<boost::filesystem::path> &fileList, boost::filesystem::path directory)
    {
        if (!boost::filesystem::exists(directory))
        {
            throw std::runtime_error("Attempt to write to non-existent directory: " + directory.string());
        }
        boost::filesystem::directory_iterator dirIter(directory);
        boost::filesystem::directory_iterator dirIterEnd;

        while (dirIter != dirIterEnd)
        {
            if (boost::filesystem::exists(*dirIter))
            {
                if (boost::filesystem::is_directory(*dirIter)){
                    this->addFiles(fileList, *dirIter);
                }
                else
                {
                    fileList.push_back((*dirIter));
                }
            }

            ++dirIter;
        }
    }

    void MissionRecord::addFile(lindenb::io::Tar& archive, boost::filesystem::path path)
    {
        std::string file_name_in_archive = path.relative_path().normalize().string();
        std::replace(file_name_in_archive.begin(), file_name_in_archive.end(), '\\', '/');
        file_name_in_archive = file_name_in_archive.substr(2, file_name_in_archive.size());
        archive.putFile(path.string().c_str(), file_name_in_archive.c_str());
    }

    bool MissionRecord::isRecording() const
    {
        return this->spec.isRecording();
    }

    bool MissionRecord::isRecordingMP4() const
    {
        return this->spec.is_recording_mp4;
    }

    bool MissionRecord::isRecordingObservations() const
    {
        return this->spec.is_recording_observations;
    }

    bool MissionRecord::isRecordingRewards() const
    {
        return this->spec.is_recording_rewards;
    }

    bool MissionRecord::isRecordingCommands() const
    {
        return this->spec.is_recording_commands;
    }

    std::string MissionRecord::getMP4Path() const
    {
        return this->mp4_path;
    }

    int64_t MissionRecord::getMP4BitRate() const
    {
        return this->spec.mp4_bit_rate;
    }

    int MissionRecord::getMP4FramesPerSecond() const
    {
        return this->spec.mp4_fps;
    }

    std::string MissionRecord::getObservationsPath() const
    {
        return this->observations_path;
    }

    std::string MissionRecord::getRewardsPath() const
    {
        return this->rewards_path;
    }

    std::string MissionRecord::getCommandsPath() const
    {
        return this->commands_path;
    }

    std::string MissionRecord::getMissionInitPath() const
    {
        return this->mission_init_path;
    }

    std::string MissionRecord::getTemporaryDirectory() const
    {
        if (!this->spec.isRecording()){
            throw std::runtime_error("Mission is not being recorded.");
        }

        if (boost::filesystem::exists(this->temp_dir)){
            return this->temp_dir.string();
        }
        else{
            throw std::runtime_error("Mission record does not yet exist. Temporary directory will be created once a mission has begun.");
        }
    }
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <string.h>
#include <stdexcept>
#include <vector>

#include "child.h"
#include "bmi_child.hxx"

#define VERBOSE (false)
#define DEBUG

#if defined (DEBUG)
# define CHECK_OR_THROW(assertion, err) { if (!(assertion)) throw err; }
#else
# define CHECK_OR_THROW(assertion, err) { }
#endif

void Model::Initialize (std::string file) {
  this->model.Initialize(file);
}

void Model::Update () {
	if (this->model.initialized == false)
    throw CLASS_NOT_INITIALIZED;

  this->model.RunOneStorm ();
  this->model.MaskNodesBelowElevation (0);
}

void Model::UpdateUntil (double t) {
  double dt;

  dt = t - this->GetCurrentTime ();
  if (dt > 0)
    this->model.Run (dt);
  this->model.MaskNodesBelowElevation (0);
}

void Model::Finalize () {
  this->model.CleanUp ();
}

std::string Model::GetComponentName () {
  return "Child";
}

int Model::GetInputItemCount (void) {
  return this->input_var_name_count;
}

int Model::GetOutputItemCount (void) {
  return this->output_var_name_count;
}

std::vector<std::string>
Model::GetInputVarNames () {
  std::vector<std::string> names;

  for (int i=0; i<this->input_var_name_count; i++)
    names.push_back(this->input_var_names[i]);

  return names;
}

std::vector<std::string>
Model::GetOutputVarNames () {
  std::vector<std::string> names;

  for (int i=0; i<this->output_var_name_count; i++)
    names.push_back(this->output_var_names[i]);

  return names;
}

std::string
Model::GetVarType (std::string name) {
  if (name.compare("land_surface__elevation") == 0 ) {
    return "double";
  } else if (name.compare("sea_bottom_surface__elevation") == 0 ) {
    return "double";
  } else if (name.compare("sea_floor_bedrock_surface__elevation") == 0 ) {
    return "double";
  } else if (name.compare("bedrock_surface__elevation") == 0 ) {
    return "double";
  } else if (name.compare("bedrock_surface__elevation_increment") == 0 ) {
    return "double";
  } else if (name.compare("land_surface__elevation_increment") == 0 ) {
    return "double";
  } else if (name.compare("sediment__erosion_rate") == 0 ) {
    return "double";
  } else if (name.compare("channel_water__discharge") == 0 ) {
    return "double";
  } else if (name.compare("channel_water_sediment~bedload__mass_flow_rate") == 0 ) {
    return "double";
  } else {
    throw BAD_VAR_NAME;
  }
}

std::string
Model::GetVarUnits (std::string name) {
  if (name.compare("land_surface__elevation") == 0 ) {
    return "m";
  } else if (name.compare("sea_bottom_surface__elevation") == 0 ) {
    return "m";
  } else if (name.compare("sea_floor_bedrock_surface__elevation") == 0 ) {
    return "m";
  } else if (name.compare("bedrock_surface__elevation") == 0 ) {
    return "m";
  } else if (name.compare("bedrock_surface__elevation_increment") == 0 ) {
    return "m";
  } else if (name.compare("land_surface__elevation_increment") == 0 ) {
    return "m";
  } else if (name.compare("sediment__erosion_rate") == 0 ) {
    return "m / s";
  } else if (name.compare("channel_water__discharge") == 0 ) {
    return "m^3 / s";
  } else if (name.compare("channel_water_sediment~bedload__mass_flow_rate") == 0 ) {
    return "kg / s";
  } else {
    throw BAD_VAR_NAME;
  }
}

int Model::GetVarGrid (std::string name) {
  int grid_id;

  if (name.compare("land_surface__elevation") == 0 ) {
    grid_id = 0;
  } else if (name.compare("sea_bottom_surface__elevation") == 0 ) {
    grid_id = 0;
  } else if (name.compare("sea_floor_bedrock_surface__elevation") == 0 ) {
    grid_id = 0;
  } else if (name.compare("bedrock_surface__elevation") == 0 ) {
    grid_id = 0;
  } else if (name.compare("bedrock_surface__elevation_increment") == 0 ) {
    grid_id = 0;
  } else if (name.compare("land_surface__elevation_increment") == 0 ) {
    grid_id = 0;
  } else if (name.compare("sediment__erosion_rate") == 0 ) {
    grid_id = 0;
  } else if (name.compare("channel_water__discharge") == 0 ) {
    grid_id = 0;
  } else if (name.compare("channel_water_sediment~bedload__mass_flow_rate") == 0 ) {
    grid_id = 0;
  } else {
    throw std::runtime_error("unknown var name");
    // throw BAD_VAR_NAME;
  }
  return grid_id;
}

int Model::GetGridRank (const int grid_id) {
  int rank;

  if (grid_id == 0) {
    rank = 2;
  } else {
    throw BAD_VAR_NAME;
  }
  return rank;
}

int Model::GetGridSize (const int grid_id) {
  int size = 0;
  size = this->model.mesh->getNodeList()->getSize();
  return size;
}

double Model::GetStartTime () {
  return 0.0;
}

double Model::GetCurrentTime () {
  double now = 0.;
  now = this->model.time->getCurrentTime ();
  return now;
}

double Model::GetEndTime () {
  double stop = 0.;
  stop = this->model.time->getCurrentTime () + this->model.time->RemainingTime ();
  return stop;
}

std::string
Model::GetTimeUnits () {
  return "year";
}

double Model::GetTimeStep () {
  return -1.;
}

int Model::GetVarItemsize(std::string name) {
  int itemsize = 0;

  if (name.compare("land_surface__elevation") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("sea_bottom_surface__elevation") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("sea_floor_bedrock_surface__elevation") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("bedrock_surface__elevation") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("bedrock_surface__elevation_increment") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("land_surface__elevation_increment") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("sediment__erosion_rate") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("channel_water__discharge") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("channel_water_sediment~bedload__mass_flow_rate") == 0 ) {
    itemsize = sizeof(double);
  } else {
    throw BAD_VAR_NAME;
  }
  return itemsize;
}

int Model::GetVarNbytes(std::string name) {
  const int itemsize = GetVarItemsize(name);
  const int id = GetVarGrid(name);
  const int size = GetGridSize(id);

  return itemsize * size;
}

std::string Model::GetVarLocation(std::string name) {
  return "node";
}

void Model::GetValue(std::string name, void * const dest) {
  if (name.compare("land_surface__elevation") == 0 ) {
    this->model.CopyNodeElevations ((double*)dest);
  } else if (name.compare("sea_bottom_surface__elevation") == 0 ) {
    this->model.CopyNodeElevations ((double*)dest);
  } else if (name.compare("land_surface__elevation_increment") == 0 ) {
    this->model.CopyNodeElevations ((double*)dest);
  } else if (name.compare("sediment__erosion_rate") == 0 ) {
    this->model.CopyNodeErosion ((double*)dest);
  } else if (name.compare("channel_water__discharge") == 0 ) {
    this->model.CopyNodeDischarge ((double*)dest);
  } else if (name.compare("channel_water_sediment~bedload__mass_flow_rate") == 0 ) {
    this->model.CopyNodeSedimentFlux ((double*)dest);
  } else {
    throw BAD_VAR_NAME;
  }
}

void *Model::GetValuePtr(std::string name) {
  throw NotImplemented();
}

void Model::GetValueAtIndices(std::string name, void *dest, int *inds, int count) {
  throw NotImplemented();
}

void Model::SetValue (std::string name, void *vals) {
  if (name.compare("land_surface__elevation") == 0 ) {
    return this->model.SetNodeElevations ((double*)vals);
  } else if (name.compare("sea_bottom_surface__elevation") == 0 ) {
    return this->model.SetNodeElevations ((double*)vals);
  } else if (name.compare("sea_floor_bedrock_surface__elevation") == 0 ) {
    return this->model.SetNodeElevations ((double*)vals);
  } else if (name.compare("bedrock_surface__elevation") == 0 ) {
    return this->model.SetNodeElevations ((double*)vals);
  } else if (name.compare("bedrock_surface__elevation_increment") == 0 ) {
    return this->model.SetNodeUplift ((double*)vals);
  } else {
    throw BAD_VAR_NAME;
  }
}

void Model::SetValueAtIndices(std::string name, int *inds, int len, void *src) {
  throw NotImplemented();
}

void Model::GetGridShape(const int grid, int *shape) {
  throw NotImplemented();
}

void Model::GetGridSpacing(const int grid, double *spacing) {
  throw NotImplemented();
}

void Model::GetGridOrigin(const int grid, double *origin) {
  throw NotImplemented();
}

void Model::GetGridX (const int grid_id, double * const x) {
  if (grid_id == 0) {
    tLNode *current_node;
    tMesh<tLNode>::nodeListIter_t ni( this->model.mesh->getNodeList() );

    for (current_node=ni.FirstP(); !ni.AtEnd(); current_node=ni.NextP()) {
      x[current_node->getPermID ()] = current_node->getX ();
    }

  } else {
    throw bmi::BMI_FAILURE;
  }
}

void Model::GetGridY (const int grid_id, double * const y) {
  if (grid_id == 0) {
    tLNode *current_node;
    tMesh<tLNode>::nodeListIter_t ni( this->model.mesh->getNodeList() );

    for (current_node=ni.FirstP(); !ni.AtEnd(); current_node=ni.NextP()) {
      y[current_node->getPermID ()] = current_node->getY ();
    }
  } else {
    throw bmi::BMI_FAILURE;
  }
}

void Model::GetGridZ (const int grid_id, double * const y) {
  throw NotImplemented();
}

int Model::GetGridNodeCount(const int grid_id) {
  return this->model.mesh->getNodeList()->getSize();
}

int Model::GetGridEdgeCount(const int grid_id) {
  return 0;
  // return this->model.mesh->getEdgeList()->getSize();
}

int Model::GetGridFaceCount(const int grid_id) {
  if (grid_id == 0) {
    return 0;
    // return this->model.mesh->getTriList()->getSize();
  } else {
    throw bmi::BMI_FAILURE;
  }
}

void Model::GetGridNodesPerFace (const int grid_id, int * edges_per_face) {
  if (grid_id == 0) {
    int i = 0;
    const int n_faces = GetGridFaceCount(grid_id);
    for (i=0; i<n_faces; i++)
      edges_per_face[i] = 3;
  } else {
    throw bmi::BMI_FAILURE;
  }
}

void Model::GetGridFaceNodes (const int grid_id, int * face_nodes) {
  if (grid_id == 0) {
    {
      int i = 0;
      tMesh<tLNode>::triListIter_t ti(this->model.mesh->getTriList());
      for (tTriangle * current_tri=ti.FirstP(); !ti.AtEnd();
           i+=3, current_tri=ti.NextP ()) {
        face_nodes[i] = current_tri->pPtr(0)->getPermID();
        face_nodes[i+1] = current_tri->pPtr(1)->getPermID();
        face_nodes[i+2] = current_tri->pPtr(2)->getPermID();
      }
    }
  } else {
    throw bmi::BMI_FAILURE;
  }
}

void Model::GetGridEdgeNodes(const int grid, int *edge_nodes) {
  throw NotImplemented();
}

void Model::GetGridFaceEdges(const int grid, int *face_edges) {
  throw NotImplemented();
}

std::string Model::GetGridType (const int grid_id) {
  if (grid_id == 0) {
    return "unstructured";
    // return "unstructured_triangular";
  } else {
    throw bmi::BMI_FAILURE;
  }
}
<commit_msg>implement edge methods for bmi<commit_after>#include <stdio.h>
#include <string.h>
#include <stdexcept>
#include <vector>

#include "child.h"
#include "bmi_child.hxx"

#define VERBOSE (false)
#define DEBUG

#if defined (DEBUG)
# define CHECK_OR_THROW(assertion, err) { if (!(assertion)) throw err; }
#else
# define CHECK_OR_THROW(assertion, err) { }
#endif

void Model::Initialize (std::string file) {
  this->model.Initialize(file);
}

void Model::Update () {
	if (this->model.initialized == false)
    throw CLASS_NOT_INITIALIZED;

  this->model.RunOneStorm ();
  this->model.MaskNodesBelowElevation (0);
}

void Model::UpdateUntil (double t) {
  double dt;

  dt = t - this->GetCurrentTime ();
  if (dt > 0)
    this->model.Run (dt);
  this->model.MaskNodesBelowElevation (0);
}

void Model::Finalize () {
  this->model.CleanUp ();
}

std::string Model::GetComponentName () {
  return "Child";
}

int Model::GetInputItemCount (void) {
  return this->input_var_name_count;
}

int Model::GetOutputItemCount (void) {
  return this->output_var_name_count;
}

std::vector<std::string>
Model::GetInputVarNames () {
  std::vector<std::string> names;

  for (int i=0; i<this->input_var_name_count; i++)
    names.push_back(this->input_var_names[i]);

  return names;
}

std::vector<std::string>
Model::GetOutputVarNames () {
  std::vector<std::string> names;

  for (int i=0; i<this->output_var_name_count; i++)
    names.push_back(this->output_var_names[i]);

  return names;
}

std::string
Model::GetVarType (std::string name) {
  if (name.compare("land_surface__elevation") == 0 ) {
    return "double";
  } else if (name.compare("sea_bottom_surface__elevation") == 0 ) {
    return "double";
  } else if (name.compare("sea_floor_bedrock_surface__elevation") == 0 ) {
    return "double";
  } else if (name.compare("bedrock_surface__elevation") == 0 ) {
    return "double";
  } else if (name.compare("bedrock_surface__elevation_increment") == 0 ) {
    return "double";
  } else if (name.compare("land_surface__elevation_increment") == 0 ) {
    return "double";
  } else if (name.compare("sediment__erosion_rate") == 0 ) {
    return "double";
  } else if (name.compare("channel_water__discharge") == 0 ) {
    return "double";
  } else if (name.compare("channel_water_sediment~bedload__mass_flow_rate") == 0 ) {
    return "double";
  } else {
    throw BAD_VAR_NAME;
  }
}

std::string
Model::GetVarUnits (std::string name) {
  if (name.compare("land_surface__elevation") == 0 ) {
    return "m";
  } else if (name.compare("sea_bottom_surface__elevation") == 0 ) {
    return "m";
  } else if (name.compare("sea_floor_bedrock_surface__elevation") == 0 ) {
    return "m";
  } else if (name.compare("bedrock_surface__elevation") == 0 ) {
    return "m";
  } else if (name.compare("bedrock_surface__elevation_increment") == 0 ) {
    return "m";
  } else if (name.compare("land_surface__elevation_increment") == 0 ) {
    return "m";
  } else if (name.compare("sediment__erosion_rate") == 0 ) {
    return "m / s";
  } else if (name.compare("channel_water__discharge") == 0 ) {
    return "m^3 / s";
  } else if (name.compare("channel_water_sediment~bedload__mass_flow_rate") == 0 ) {
    return "kg / s";
  } else {
    throw BAD_VAR_NAME;
  }
}

int Model::GetVarGrid (std::string name) {
  int grid_id;

  if (name.compare("land_surface__elevation") == 0 ) {
    grid_id = 0;
  } else if (name.compare("sea_bottom_surface__elevation") == 0 ) {
    grid_id = 0;
  } else if (name.compare("sea_floor_bedrock_surface__elevation") == 0 ) {
    grid_id = 0;
  } else if (name.compare("bedrock_surface__elevation") == 0 ) {
    grid_id = 0;
  } else if (name.compare("bedrock_surface__elevation_increment") == 0 ) {
    grid_id = 0;
  } else if (name.compare("land_surface__elevation_increment") == 0 ) {
    grid_id = 0;
  } else if (name.compare("sediment__erosion_rate") == 0 ) {
    grid_id = 0;
  } else if (name.compare("channel_water__discharge") == 0 ) {
    grid_id = 0;
  } else if (name.compare("channel_water_sediment~bedload__mass_flow_rate") == 0 ) {
    grid_id = 0;
  } else {
    throw std::runtime_error("unknown var name");
    // throw BAD_VAR_NAME;
  }
  return grid_id;
}

int Model::GetGridRank (const int grid_id) {
  int rank;

  if (grid_id == 0) {
    rank = 2;
  } else {
    throw BAD_VAR_NAME;
  }
  return rank;
}

int Model::GetGridSize (const int grid_id) {
  int size = 0;
  size = this->model.mesh->getNodeList()->getSize();
  return size;
}

double Model::GetStartTime () {
  return 0.0;
}

double Model::GetCurrentTime () {
  double now = 0.;
  now = this->model.time->getCurrentTime ();
  return now;
}

double Model::GetEndTime () {
  double stop = 0.;
  stop = this->model.time->getCurrentTime () + this->model.time->RemainingTime ();
  return stop;
}

std::string
Model::GetTimeUnits () {
  return "year";
}

double Model::GetTimeStep () {
  return -1.;
}

int Model::GetVarItemsize(std::string name) {
  int itemsize = 0;

  if (name.compare("land_surface__elevation") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("sea_bottom_surface__elevation") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("sea_floor_bedrock_surface__elevation") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("bedrock_surface__elevation") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("bedrock_surface__elevation_increment") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("land_surface__elevation_increment") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("sediment__erosion_rate") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("channel_water__discharge") == 0 ) {
    itemsize = sizeof(double);
  } else if (name.compare("channel_water_sediment~bedload__mass_flow_rate") == 0 ) {
    itemsize = sizeof(double);
  } else {
    throw BAD_VAR_NAME;
  }
  return itemsize;
}

int Model::GetVarNbytes(std::string name) {
  const int itemsize = GetVarItemsize(name);
  const int id = GetVarGrid(name);
  const int size = GetGridSize(id);

  return itemsize * size;
}

std::string Model::GetVarLocation(std::string name) {
  return "node";
}

void Model::GetValue(std::string name, void * const dest) {
  if (name.compare("land_surface__elevation") == 0 ) {
    this->model.CopyNodeElevations ((double*)dest);
  } else if (name.compare("sea_bottom_surface__elevation") == 0 ) {
    this->model.CopyNodeElevations ((double*)dest);
  } else if (name.compare("land_surface__elevation_increment") == 0 ) {
    this->model.CopyNodeElevations ((double*)dest);
  } else if (name.compare("sediment__erosion_rate") == 0 ) {
    this->model.CopyNodeErosion ((double*)dest);
  } else if (name.compare("channel_water__discharge") == 0 ) {
    this->model.CopyNodeDischarge ((double*)dest);
  } else if (name.compare("channel_water_sediment~bedload__mass_flow_rate") == 0 ) {
    this->model.CopyNodeSedimentFlux ((double*)dest);
  } else {
    throw BAD_VAR_NAME;
  }
}

void *Model::GetValuePtr(std::string name) {
  throw NotImplemented();
}

void Model::GetValueAtIndices(std::string name, void *dest, int *inds, int count) {
  throw NotImplemented();
}

void Model::SetValue (std::string name, void *vals) {
  if (name.compare("land_surface__elevation") == 0 ) {
    return this->model.SetNodeElevations ((double*)vals);
  } else if (name.compare("sea_bottom_surface__elevation") == 0 ) {
    return this->model.SetNodeElevations ((double*)vals);
  } else if (name.compare("sea_floor_bedrock_surface__elevation") == 0 ) {
    return this->model.SetNodeElevations ((double*)vals);
  } else if (name.compare("bedrock_surface__elevation") == 0 ) {
    return this->model.SetNodeElevations ((double*)vals);
  } else if (name.compare("bedrock_surface__elevation_increment") == 0 ) {
    return this->model.SetNodeUplift ((double*)vals);
  } else {
    throw BAD_VAR_NAME;
  }
}

void Model::SetValueAtIndices(std::string name, int *inds, int len, void *src) {
  throw NotImplemented();
}

void Model::GetGridShape(const int grid, int *shape) {
  throw NotImplemented();
}

void Model::GetGridSpacing(const int grid, double *spacing) {
  throw NotImplemented();
}

void Model::GetGridOrigin(const int grid, double *origin) {
  throw NotImplemented();
}

void Model::GetGridX (const int grid_id, double * const x) {
  if (grid_id == 0) {
    tLNode *current_node;
    tMesh<tLNode>::nodeListIter_t ni( this->model.mesh->getNodeList() );

    for (current_node=ni.FirstP(); !ni.AtEnd(); current_node=ni.NextP()) {
      x[current_node->getPermID ()] = current_node->getX ();
    }

  } else {
    throw bmi::BMI_FAILURE;
  }
}

void Model::GetGridY (const int grid_id, double * const y) {
  if (grid_id == 0) {
    tLNode *current_node;
    tMesh<tLNode>::nodeListIter_t ni( this->model.mesh->getNodeList() );

    for (current_node=ni.FirstP(); !ni.AtEnd(); current_node=ni.NextP()) {
      y[current_node->getPermID ()] = current_node->getY ();
    }
  } else {
    throw bmi::BMI_FAILURE;
  }
}

void Model::GetGridZ (const int grid_id, double * const y) {
  throw NotImplemented();
}

int Model::GetGridNodeCount(const int grid_id) {
  return this->model.mesh->getNodeList()->getSize();
}

int Model::GetGridEdgeCount(const int grid_id) {
  return this->model.mesh->getEdgeList()->getSize();
}

int Model::GetGridFaceCount(const int grid_id) {
  if (grid_id == 0) {
    return this->model.mesh->getTriList()->getSize();
  } else {
    throw bmi::BMI_FAILURE;
  }
}

void Model::GetGridNodesPerFace (const int grid_id, int * edges_per_face) {
  if (grid_id == 0) {
    int i = 0;
    const int n_faces = GetGridFaceCount(grid_id);
    for (i=0; i<n_faces; i++)
      edges_per_face[i] = 3;
  } else {
    throw bmi::BMI_FAILURE;
  }
}

void Model::GetGridFaceNodes (const int grid_id, int * face_nodes) {
  if (grid_id == 0) {
    {
      int i = 0;
      tMesh<tLNode>::triListIter_t ti(this->model.mesh->getTriList());
      for (tTriangle * current_tri=ti.FirstP(); !ti.AtEnd();
           i+=3, current_tri=ti.NextP ()) {
        face_nodes[i] = current_tri->pPtr(0)->getPermID();
        face_nodes[i+1] = current_tri->pPtr(1)->getPermID();
        face_nodes[i+2] = current_tri->pPtr(2)->getPermID();
      }
    }
  } else {
    throw bmi::BMI_FAILURE;
  }
}

void Model::GetGridEdgeNodes(const int grid_id, int *edge_nodes) {
  if (grid_id == 0) {
    int i = 0;
    tMesh<tLNode>::edgeListIter_t edgeIter(this->model.mesh->getEdgeList());
    tEdge *current_edge;

    for (
        current_edge=edgeIter.FirstP();
        !edgeIter.AtEnd();
        i += 2, current_edge=edgeIter.NextP()
    ) {
      edge_nodes[i] = current_edge->getOriginPtr()->getPermID();
      edge_nodes[i + 1] = current_edge->getDestinationPtr()->getPermID();
    }
  } else {
    throw bmi::BMI_FAILURE;
  }
}

void Model::GetGridFaceEdges(const int grid, int *face_edges) {
  throw NotImplemented();
}

std::string Model::GetGridType (const int grid_id) {
  if (grid_id == 0) {
    return "unstructured";
    // return "unstructured_triangular";
  } else {
    throw bmi::BMI_FAILURE;
  }
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    otherLookupTable.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm 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 notice for more information.

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

// .NAME
// .SECTION Description
// this program tests the LookupTable

#include "vtkLookupTable.h"
#include "vtkLogLookupTable.h"
#include "vtkDebugLeaks.h"

void TestOLT(vtkLookupTable *lut1)
{
  // actual test

  lut1->SetRange(1,1024);

  lut1->Allocate (1024);
  lut1->SetRampToLinear();
  lut1->Build();

  double rgb[3];
  lut1->GetColor(0, rgb);

  lut1->GetOpacity(0);

  lut1->GetTableValue(10,rgb);
  lut1->GetTableValue(10);

  unsigned char output[4*1024];

  int bitA = 1;
  lut1->MapScalarsThroughTable2((void *) &bitA, output, VTK_BIT,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) &bitA, output, VTK_CHAR,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) &bitA, output, VTK_CHAR,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) &bitA, output, VTK_CHAR,
                                2, 1, VTK_LUMINANCE);

  char charA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) charA, output, VTK_CHAR,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) charA, output, VTK_CHAR,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) charA, output, VTK_CHAR,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) charA, output, VTK_CHAR,
                                2, 1, VTK_LUMINANCE);

  unsigned char ucharA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) ucharA, output, VTK_UNSIGNED_CHAR,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) ucharA, output, VTK_UNSIGNED_CHAR,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) ucharA, output, VTK_UNSIGNED_CHAR,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) ucharA, output, VTK_UNSIGNED_CHAR,
                                2, 1, VTK_LUMINANCE);

  int intA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) intA, output, VTK_INT,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) intA, output, VTK_INT,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) intA, output, VTK_INT,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) intA, output, VTK_INT,
                                2, 1, VTK_LUMINANCE);

  unsigned int uintA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) uintA, output, VTK_UNSIGNED_INT,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) uintA, output, VTK_UNSIGNED_INT,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) uintA, output, VTK_UNSIGNED_INT,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) uintA, output, VTK_UNSIGNED_INT,
                                2, 1, VTK_LUMINANCE);

  long longA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) longA, output, VTK_LONG,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) longA, output, VTK_LONG,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) longA, output, VTK_LONG,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) longA, output, VTK_LONG,
                                2, 1, VTK_LUMINANCE);

  unsigned long ulongA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) ulongA, output, VTK_UNSIGNED_LONG,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) ulongA, output, VTK_UNSIGNED_LONG,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) ulongA, output, VTK_UNSIGNED_LONG,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) ulongA, output, VTK_UNSIGNED_LONG, 2, 1, VTK_LUMINANCE);

  short shortA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) shortA, output, VTK_SHORT,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) shortA, output, VTK_SHORT,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) shortA, output, VTK_SHORT,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) shortA, output, VTK_SHORT,
                                2, 1, VTK_LUMINANCE);

  unsigned short ushortA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) ushortA, output,
                                VTK_UNSIGNED_SHORT, 2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) ushortA, output,
                                VTK_UNSIGNED_SHORT, 2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) ushortA, output,
                                VTK_UNSIGNED_SHORT, 2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) ushortA, output,
                                VTK_UNSIGNED_SHORT, 2, 1, VTK_LUMINANCE);

  float floatA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) floatA, output,
                                VTK_FLOAT, 2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) floatA, output,
                                VTK_FLOAT, 2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) floatA, output,
                                VTK_FLOAT, 2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) floatA, output,
                                VTK_FLOAT, 2, 1, VTK_LUMINANCE);

  double doubleA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) doubleA, output,
                                VTK_DOUBLE, 2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) doubleA, output,
                                VTK_DOUBLE, 2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) doubleA, output,
                                VTK_DOUBLE, 2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) doubleA, output,
                                VTK_DOUBLE, 2, 1, VTK_LUMINANCE);

}

int otherLookupTable(int,char *[])
{
  vtkDebugLeaks::PromptUserOff();

  vtkLookupTable *lut1 = vtkLookupTable::New();
  lut1->SetAlpha(1.0);
  lut1->SetScaleToLinear();
  TestOLT(lut1);
  lut1->SetAlpha(.5);
  TestOLT(lut1);
  lut1->Delete();

  vtkLogLookupTable *lut2 = vtkLogLookupTable::New();
  lut2->SetAlpha(1.0);
  lut2->SetScaleToLog10();
  TestOLT(lut2);
  lut2->SetAlpha(.5);
  TestOLT(lut2);
  lut2->Delete();

  return 0;
}
<commit_msg>BUG: Need an array of 4<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    otherLookupTable.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm 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 notice for more information.

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

// .NAME
// .SECTION Description
// this program tests the LookupTable

#include "vtkLookupTable.h"
#include "vtkLogLookupTable.h"
#include "vtkDebugLeaks.h"

void TestOLT(vtkLookupTable *lut1)
{
  // actual test

  lut1->SetRange(1,1024);

  lut1->Allocate (1024);
  lut1->SetRampToLinear();
  lut1->Build();

  double rgb[4];
  lut1->GetColor(0, rgb);

  lut1->GetOpacity(0);

  lut1->GetTableValue(10,rgb);
  lut1->GetTableValue(10);

  unsigned char output[4*1024];

  int bitA = 1;
  lut1->MapScalarsThroughTable2((void *) &bitA, output, VTK_BIT,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) &bitA, output, VTK_CHAR,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) &bitA, output, VTK_CHAR,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) &bitA, output, VTK_CHAR,
                                2, 1, VTK_LUMINANCE);

  char charA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) charA, output, VTK_CHAR,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) charA, output, VTK_CHAR,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) charA, output, VTK_CHAR,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) charA, output, VTK_CHAR,
                                2, 1, VTK_LUMINANCE);

  unsigned char ucharA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) ucharA, output, VTK_UNSIGNED_CHAR,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) ucharA, output, VTK_UNSIGNED_CHAR,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) ucharA, output, VTK_UNSIGNED_CHAR,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) ucharA, output, VTK_UNSIGNED_CHAR,
                                2, 1, VTK_LUMINANCE);

  int intA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) intA, output, VTK_INT,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) intA, output, VTK_INT,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) intA, output, VTK_INT,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) intA, output, VTK_INT,
                                2, 1, VTK_LUMINANCE);

  unsigned int uintA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) uintA, output, VTK_UNSIGNED_INT,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) uintA, output, VTK_UNSIGNED_INT,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) uintA, output, VTK_UNSIGNED_INT,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) uintA, output, VTK_UNSIGNED_INT,
                                2, 1, VTK_LUMINANCE);

  long longA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) longA, output, VTK_LONG,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) longA, output, VTK_LONG,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) longA, output, VTK_LONG,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) longA, output, VTK_LONG,
                                2, 1, VTK_LUMINANCE);

  unsigned long ulongA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) ulongA, output, VTK_UNSIGNED_LONG,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) ulongA, output, VTK_UNSIGNED_LONG,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) ulongA, output, VTK_UNSIGNED_LONG,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) ulongA, output, VTK_UNSIGNED_LONG, 2, 1, VTK_LUMINANCE);

  short shortA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) shortA, output, VTK_SHORT,
                                2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) shortA, output, VTK_SHORT,
                                2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) shortA, output, VTK_SHORT,
                                2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) shortA, output, VTK_SHORT,
                                2, 1, VTK_LUMINANCE);

  unsigned short ushortA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) ushortA, output,
                                VTK_UNSIGNED_SHORT, 2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) ushortA, output,
                                VTK_UNSIGNED_SHORT, 2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) ushortA, output,
                                VTK_UNSIGNED_SHORT, 2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) ushortA, output,
                                VTK_UNSIGNED_SHORT, 2, 1, VTK_LUMINANCE);

  float floatA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) floatA, output,
                                VTK_FLOAT, 2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) floatA, output,
                                VTK_FLOAT, 2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) floatA, output,
                                VTK_FLOAT, 2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) floatA, output,
                                VTK_FLOAT, 2, 1, VTK_LUMINANCE);

  double doubleA[2] = {1, 10};
  lut1->MapScalarsThroughTable2((void *) doubleA, output,
                                VTK_DOUBLE, 2, 1, VTK_RGBA);
  lut1->MapScalarsThroughTable2((void *) doubleA, output,
                                VTK_DOUBLE, 2, 1, VTK_RGB);
  lut1->MapScalarsThroughTable2((void *) doubleA, output,
                                VTK_DOUBLE, 2, 1, VTK_LUMINANCE_ALPHA);
  lut1->MapScalarsThroughTable2((void *) doubleA, output,
                                VTK_DOUBLE, 2, 1, VTK_LUMINANCE);

}

int otherLookupTable(int,char *[])
{
  vtkDebugLeaks::PromptUserOff();

  vtkLookupTable *lut1 = vtkLookupTable::New();
  lut1->SetAlpha(1.0);
  lut1->SetScaleToLinear();
  TestOLT(lut1);
  lut1->SetAlpha(.5);
  TestOLT(lut1);
  lut1->Delete();

  vtkLogLookupTable *lut2 = vtkLogLookupTable::New();
  lut2->SetAlpha(1.0);
  lut2->SetScaleToLog10();
  TestOLT(lut2);
  lut2->SetAlpha(.5);
  TestOLT(lut2);
  lut2->Delete();

  return 0;
}
<|endoftext|>


<commit_before>//
// This file is part of SLogLib; you can redistribute it and/or
// modify it under the terms of the MIT License.
// Author: Saurabh Garg (saurabhgarg@mysoc.net)
//

#include <QtCore/QThread>
#include <QtWidgets/QScrollBar>
#include "SLogLib/SLogLib.h"
#include "QWidgetLogger.h"

using namespace SLogLib;

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
QWidgetLogger::QWidgetLogger(SLogLib::AbstractFormatter* formatter)
	: AbstractLoggingDevice(formatter)
{
	mLogTextEdit = new SLogTextEdit();
}
QWidgetLogger::QWidgetLogger(SLogLib::AbstractFormatter* formatter, const std::string& name)
	: AbstractLoggingDevice(formatter, name), mLogTextEdit(nullptr)
{
	mLogTextEdit = new SLogTextEdit();
}
QWidgetLogger::~QWidgetLogger()
{
	//mLogTextEdit is automatically deleted by Qt.
	AbstractLoggingDevice::_FlushBufferedMessages();
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
void QWidgetLogger::_WriteMessage(const std::string& message)
{
	mLogTextEdit->_WriteMessage(message);
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
SLogTextEdit::SLogTextEdit(QWidget* parent) : QTextEdit(parent)
{
	setReadOnly(true);
	setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
	setAcceptRichText(false);
	setContextMenuPolicy(Qt::NoContextMenu);
	setUndoRedoEnabled(false);

	QFont font("Monospace");
	font.setStyleHint(QFont::TypeWriter);
	font.setPointSize(12);
	setFont(font);

	connect(this, SIGNAL(WriteMessageInMainThread(const QString&)), this, SLOT(WriteMessage(const QString&)));
}
void SLogTextEdit::_WriteMessage(const std::string& message)
{
	QString _message = message.c_str();

	// In Qt, any UI element such as QTextEdit can only be updated from the
	// main thread i.e the thread in which QEventLoop is running. Here we check,
	// if the current thread is the thread which created this QTextEdit. If it is not,
	// then emit a signal which is connected to the WriteMessage(const QString&) slot.
	// Since, slots are always received in the main thread, message can be logged successfully.
	if(QThread::currentThread() != thread())
	{
		emit WriteMessageInMainThread(_message);
	}
	else
	{
		WriteMessage(_message);
	}
}
void SLogTextEdit::WriteMessage(const QString& message)
{
	Q_ASSERT(QThread::currentThread() == thread());

	append(message);

	QScrollBar* _scrollBar = verticalScrollBar();
	if(_scrollBar)
	{
		_scrollBar->setValue(_scrollBar->maximum());
	}
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
<commit_msg>Deleted irrelevant comment.<commit_after>//
// This file is part of SLogLib; you can redistribute it and/or
// modify it under the terms of the MIT License.
// Author: Saurabh Garg (saurabhgarg@mysoc.net)
//

#include <QtCore/QThread>
#include <QtWidgets/QScrollBar>
#include "SLogLib/SLogLib.h"
#include "QWidgetLogger.h"

using namespace SLogLib;

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
QWidgetLogger::QWidgetLogger(SLogLib::AbstractFormatter* formatter)
	: AbstractLoggingDevice(formatter)
{
	mLogTextEdit = new SLogTextEdit();
}
QWidgetLogger::QWidgetLogger(SLogLib::AbstractFormatter* formatter, const std::string& name)
	: AbstractLoggingDevice(formatter, name), mLogTextEdit(nullptr)
{
	mLogTextEdit = new SLogTextEdit();
}
QWidgetLogger::~QWidgetLogger()
{
	AbstractLoggingDevice::_FlushBufferedMessages();
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
void QWidgetLogger::_WriteMessage(const std::string& message)
{
	mLogTextEdit->_WriteMessage(message);
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
SLogTextEdit::SLogTextEdit(QWidget* parent) : QTextEdit(parent)
{
	setReadOnly(true);
	setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
	setAcceptRichText(false);
	setContextMenuPolicy(Qt::NoContextMenu);
	setUndoRedoEnabled(false);

	QFont font("Monospace");
	font.setStyleHint(QFont::TypeWriter);
	font.setPointSize(12);
	setFont(font);

	connect(this, SIGNAL(WriteMessageInMainThread(const QString&)), this, SLOT(WriteMessage(const QString&)));
}
void SLogTextEdit::_WriteMessage(const std::string& message)
{
	QString _message = message.c_str();

	// In Qt, any UI element such as QTextEdit can only be updated from the
	// main thread i.e the thread in which QEventLoop is running. Here we check,
	// if the current thread is the thread which created this QTextEdit. If it is not,
	// then emit a signal which is connected to the WriteMessage(const QString&) slot.
	// Since, slots are always received in the main thread, message can be logged successfully.
	if(QThread::currentThread() != thread())
	{
		emit WriteMessageInMainThread(_message);
	}
	else
	{
		WriteMessage(_message);
	}
}
void SLogTextEdit::WriteMessage(const QString& message)
{
	Q_ASSERT(QThread::currentThread() == thread());

	append(message);

	QScrollBar* _scrollBar = verticalScrollBar();
	if(_scrollBar)
	{
		_scrollBar->setValue(_scrollBar->maximum());
	}
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
<|endoftext|>


<commit_before>/*
 * The MIT License
 *
 * Copyright 2017 Syed Ali <Syed.Ali@digital-haze.org>.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "DH_Base64.hpp"
#include "DH_BitParser.hpp"

#include <cstring>

unsigned char reverse8(unsigned char b);

size_t DigitalHaze::Base64Encode(void* src, void* dest, size_t srclen) {
	if (!src) return 0;
	if (!dest) return 0;
	if (!srclen) return 0;

	char* destBuf = (char*) dest;
	size_t destPos = 0;
	size_t i;

	// i is incremented at the bottom depending on how many
	// bytes we're reading
	for (i = 0; i < srclen;) {
		unsigned char threebytes[3];
		DigitalHaze::BitParser bytebuf(threebytes, sizeof (threebytes) * 8);

		// Read up to 3 bytes = 24 bits
		// depending on how much data we have left
		int readLen = sizeof (threebytes);
		if (srclen - i < sizeof (threebytes)) {
			// read 1 or 2 bytes
			readLen = (int) (srclen - i);
			// zero the memory as well to prevent memory corruption
			memset(threebytes, 0, sizeof (threebytes));
		}

		// Read
		// We have to flip the bits so they're in order.
		// Base64 reads bits left to right. DigitalHaze::BitParser reads bits right to left
		// So we reverse these bits so they can be read sequentially in DigitalHaze::BitParser
		for (int x = 0; x < readLen; ++x)
			threebytes[x] = reverse8(*((unsigned char*) src + i + x));

		// Read up to 4 sets of 6 bits = 24 bits
		for (int x = 0; x < readLen + 1; ++x) {
			// These 6 bits have to be re-reversed because we had put them
			// out of order when reading it sequentially
			int readVal = reverse8(bytebuf.ReadBits<int>(6)) >> 2;
			destBuf[destPos++] = IntToBase64Char(readVal);
		}

		i += readLen;
	}

	// If we're not divisble by a length of 3, add a padding of = signs
	for (; i % 3; ++i) destBuf[destPos++] = '=';
	destBuf[destPos] = '\0';

	return destPos;
}

size_t DigitalHaze::Base64Decode(void* src, void* dest, size_t srclen) {
	if (!src) return 0;
	if (!dest) return 0;
	if (!srclen) return 0;

	DigitalHaze::BitParser destBBuf(dest, 0);

	size_t discardEqualsCount = 0;
	for (size_t i = 0; i < srclen; ++i) {
		unsigned char curLetter = *((unsigned char*) src + i);
		unsigned char curValue = Base64CharToInt(curLetter);

		curValue = reverse8(curValue) >> 2;

		destBBuf.WriteBits(curValue, 6);

		// Equals are not counted, they are only for padding
		if (curLetter == (unsigned char) '=') discardEqualsCount++;
		else discardEqualsCount = 0;
	}

	size_t len = (unsigned char*) destBBuf.getDataPtr() - (unsigned char*) dest;

	// All of the bits are in reverse because of how Base64 decodes
	for (size_t i = 0; i < len; ++i)
		*((unsigned char*) dest + i) = reverse8(*((unsigned char*) dest + i));

	return len;// - discardEqualsCount;
}

char DigitalHaze::IntToBase64Char(int num) {
	if (num < 0 || num > 63) return '\0';
	char retChar;

	if (num < 26) retChar = 'A' + num;
	else if (num < 52) retChar = 'a' + (num - 26);
	else if (num < 62) retChar = '0' + (num - 52);
	else if (num == 62) retChar = '+';
	else retChar = '/';

	return retChar;
}

int DigitalHaze::Base64CharToInt(char c) {
	if (c == '+') return 62;
	else if (c == '/') return 63;
	else if (c == '=') return 0;
	else if (c >= 'A' && c <= 'Z')
		return (c - 'A');
	else if (c >= 'a' && c <= 'z')
		return (c - 'a') + 26;
	else if (c >= '0' && c <= '9')
		return (c - '0') + 52;
	return 0;
}

unsigned char reverse8(unsigned char b) {
	b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
	b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
	b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
	return b;
}<commit_msg>Updated headers so it would compile on cygwin<commit_after>/*
 * The MIT License
 *
 * Copyright 2017 Syed Ali <Syed.Ali@digital-haze.org>.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "DH_Base64.hpp"
#include "DH_BitParser.hpp"

#include <cstring>

unsigned char reverse8(unsigned char b);

size_t DigitalHaze::Base64Encode(void* src, void* dest, size_t srclen) {
	if (!src) return 0;
	if (!dest) return 0;
	if (!srclen) return 0;

	char* destBuf = (char*) dest;
	size_t destPos = 0;
	size_t i;

	// i is incremented at the bottom depending on how many
	// bytes we're reading
	for (i = 0; i < srclen;) {
		unsigned char threebytes[3];
		DigitalHaze::BitParser bytebuf(threebytes, sizeof (threebytes) * 8);

		// Read up to 3 bytes = 24 bits
		// depending on how much data we have left
		int readLen = sizeof (threebytes);
		if (srclen - i < sizeof (threebytes)) {
			// read 1 or 2 bytes
			readLen = (int) (srclen - i);
			// zero the memory as well to prevent memory corruption
			memset(threebytes, 0, sizeof (threebytes));
		}

		// Read
		// We have to flip the bits so they're in order.
		// Base64 reads bits left to right. DigitalHaze::BitParser reads bits right to left
		// So we reverse these bits so they can be read sequentially in DigitalHaze::BitParser
		for (int x = 0; x < readLen; ++x)
			threebytes[x] = reverse8(*((unsigned char*) src + i + x));

		// Read up to 4 sets of 6 bits = 24 bits
		for (int x = 0; x < readLen + 1; ++x) {
			// These 6 bits have to be re-reversed because we had put them
			// out of order when reading it sequentially
			int readVal = reverse8(bytebuf.ReadBits<int>(6)) >> 2;
			destBuf[destPos++] = IntToBase64Char(readVal);
		}

		i += readLen;
	}

	// If we're not divisble by a length of 3, add a padding of = signs
	for (; i % 3; ++i) destBuf[destPos++] = '=';
	destBuf[destPos] = '\0';

	return destPos;
}

size_t DigitalHaze::Base64Decode(void* src, void* dest, size_t srclen) {
	if (!src) return 0;
	if (!dest) return 0;
	if (!srclen) return 0;

	DigitalHaze::BitParser destBBuf(dest, 0);

	for (size_t i = 0; i < srclen; ++i) {
		unsigned char curLetter = *((unsigned char*) src + i);
		//if (curLetter != '=') {
			unsigned char curValue = Base64CharToInt(curLetter);

			curValue = reverse8(curValue) >> 2;

			destBBuf.WriteBits(curValue, 6);
		//}
	}

	size_t len = (unsigned char*) destBBuf.getDataPtr() - (unsigned char*) dest;

	// All of the bits are in reverse because of how Base64 decodes
	for (size_t i = 0; i < len; ++i)
		*((unsigned char*) dest + i) = reverse8(*((unsigned char*) dest + i));

	return len;
}

char DigitalHaze::IntToBase64Char(int num) {
	if (num < 0 || num > 63) return '\0';
	char retChar;

	if (num < 26) retChar = 'A' + num;
	else if (num < 52) retChar = 'a' + (num - 26);
	else if (num < 62) retChar = '0' + (num - 52);
	else if (num == 62) retChar = '+';
	else retChar = '/';

	return retChar;
}

int DigitalHaze::Base64CharToInt(char c) {
	if (c == '+') return 62;
	else if (c == '/') return 63;
	else if (c == '=') return 0;
	else if (c >= 'A' && c <= 'Z')
		return (c - 'A');
	else if (c >= 'a' && c <= 'z')
		return (c - 'a') + 26;
	else if (c >= '0' && c <= '9')
		return (c - '0') + 52;
	return 0;
}

unsigned char reverse8(unsigned char b) {
	b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
	b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
	b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
	return b;
}<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of duihome.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QGraphicsScene>
#include <QTimer>
#include <DuiInfoBanner>
#include <DuiWindow>
#include <DuiScene>
#include <DuiSceneManager>
#include <DuiOrientationChangeEvent>
#include "homeapplication.h"
#include "mainwindow.h"
#include "notificationmanager.h"
#include "duicompositornotificationsink.h"
#include "notificationwidgetparameterfactory.h"
#include "x11wrapper.h"

DuiCompositorNotificationSink::DuiCompositorNotificationSink() :
    orientationChangeSignalConnected(false)
{
    // Get X11 Atoms for different window types
    Display *dpy = QX11Info::display();
    windowTypeAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
    windowTypeDesktopAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
    clientListStackingAtom = X11Wrapper::XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
}

DuiCompositorNotificationSink::~DuiCompositorNotificationSink()
{
    // Destroy the remaining notifications
    foreach(uint id, idToNotification.keys()) {
        notificationDone(id, false);
    }
}

void DuiCompositorNotificationSink::addNotification(const Notification &notification)
{
    if (!canAddNotification(notification)) return;

    if (!orientationChangeSignalConnected) {
        // Get informed about orientation changes
        connect(MainWindow::instance(), SIGNAL(orientationChangeFinished(const Dui::Orientation &)), this, SLOT(rotateInfoBanners(const Dui::Orientation &)));
        orientationChangeSignalConnected = true;
    }

    if (idToNotification.contains(notification.notificationId())) {
        // The notification already exists so update it
        updateNotification(notification);
    } else if (!isDesktopWindowOnTop()) {
        // If the desktop window is not on top show an info banner
        // Create a new toplevel window for the info banner
        QGraphicsScene *scene = new QGraphicsScene;
        QGraphicsView *view = new QGraphicsView(scene);
        view->setFrameStyle(0);
        view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        view->setAttribute(Qt::WA_X11NetWmWindowTypeNotification);

        // Create a timer for the info banner; make it a child of the window so it is destroyed automatically
        QTimer *timer = new QTimer(view);
        timer->setSingleShot(true);
        connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));
        timer->setProperty("notificationId", notification.notificationId());

        // Create info banner widget
        DuiInfoBanner *infoBanner = createInfoBanner(notification);
        infoBanner->setManagedManually(true);

        // Rotate the view to the current orientation and make the view as big as the info banner and
        setViewSizeAndRotation(*view, *infoBanner);
        view->show();

        // Add the info banner widget to the scene
        scene->addItem(infoBanner);

        // Keep track of the mapping between IDs and private notification information classes
        idToNotification.insert(notification.notificationId(), new DuiCompositorNotificationSinkNotification(view, timer, infoBanner));

        // Make the info banner disappear after the timeout
        timer->start(notification.timeout());
    }
}

void DuiCompositorNotificationSink::updateNotification(const Notification &notification)
{
    DuiCompositorNotificationSinkNotification *sinkNotification = idToNotification.value(notification.notificationId());

    if (sinkNotification != NULL && sinkNotification->infoBanner != NULL) {
        // Update the info banner widget
        sinkNotification->infoBanner->setImageID(notification.parameters().value(NotificationWidgetParameterFactory::imageIdKey()).toString());
        sinkNotification->infoBanner->setBodyText(notification.parameters().value(NotificationWidgetParameterFactory::bodyKey()).toString());
        sinkNotification->infoBanner->setIconID(determineIconId(notification.parameters()));

        // Update the info banner's actions
        updateActions(sinkNotification->infoBanner, notification.parameters());
    }
}

void DuiCompositorNotificationSink::removeNotification(uint notificationId)
{
    notificationDone(notificationId, false);
}

void DuiCompositorNotificationSink::notificationDone(uint notificationId, bool notificationIdInUse)
{
    DuiCompositorNotificationSinkNotification *sinkNotification = idToNotification.take(notificationId);
    if (sinkNotification != NULL) {
        // Destroy the notification window immediately; this also destroys the timer
        QGraphicsScene *scene = sinkNotification->view->scene();
        delete sinkNotification->view;

        // Remove the info banner from the scene and destroy it
        scene->removeItem(sinkNotification->infoBanner);
        delete sinkNotification->infoBanner;

        // Destroy the scene and the notification information
        delete scene;
        delete sinkNotification;
    }

    if (notificationIdInUse) {
        idToNotification.insert(notificationId, NULL);
    }
}

void DuiCompositorNotificationSink::timeout()
{
    QTimer *timer = qobject_cast<QTimer *>(sender());

    if (timer != NULL) {
        // Get the notification ID from the timer
        bool ok = false;
        uint notificationId = timer->property("notificationId").toUInt(&ok);

        if (ok) {
            // Remove the notification
            notificationDone(notificationId, true);
        }
    }
}

DuiCompositorNotificationSink::DuiCompositorNotificationSinkNotification::DuiCompositorNotificationSinkNotification(QGraphicsView *view, QTimer *timer, DuiInfoBanner *infoBanner) :
    view(view),
    timer(timer),
    infoBanner(infoBanner)
{
}

DuiCompositorNotificationSink::DuiCompositorNotificationSinkNotification::~DuiCompositorNotificationSinkNotification()
{
}

bool DuiCompositorNotificationSink::isDesktopWindowOnTop()
{
    bool desktopOnTop = false;

    // Get a list of all windows in their stacking order
    Display *dpy = QX11Info::display();
    Atom actualType;
    int actualFormat;
    unsigned long numWindowItems, bytesLeft;
    unsigned char *windowData = NULL;
    int result = X11Wrapper::XGetWindowProperty(dpy, DefaultRootWindow(dpy), clientListStackingAtom, 0, 0x7fffffff, False, XA_WINDOW,
                 &actualType, &actualFormat, &numWindowItems, &bytesLeft, &windowData);

    if (result == Success && windowData != None && numWindowItems > 0) {
        Window *wins = (Window *)windowData;
        unsigned char *typeData = NULL;
        unsigned long numTypeItems;

        // Get the window type
        result = X11Wrapper::XGetWindowProperty(dpy, wins[numWindowItems - 1], windowTypeAtom, 0L, 16L, False, XA_ATOM,
                                                &actualType, &actualFormat, &numTypeItems, &bytesLeft, &typeData);

        if (result == Success) {
            Atom *type = (Atom *)typeData;

            // Check if the types list includes desktop
            for (unsigned int n = 0; n < numTypeItems; n++) {
                if (type[n] == windowTypeDesktopAtom) {
                    desktopOnTop = true;
                    break;
                }
            }

            X11Wrapper::XFree(typeData);
        }

        X11Wrapper::XFree(wins);
    }

    return desktopOnTop;
}

void DuiCompositorNotificationSink::rotateInfoBanners(const Dui::Orientation &orientation)
{
    foreach(DuiCompositorNotificationSinkNotification * notification, idToNotification.values()) {
        // Rotate the views of all existing notifications to the current orientation and resize their sizes accordingly
        if (notification != NULL && notification->view != NULL && notification->infoBanner != NULL) {
            QGraphicsScene *scene = notification->view->scene();
            if (scene != NULL) {
                // Notify each item on the notification view's scene about the new orientation
                DuiOrientationChangeEvent event(orientation);
                Q_FOREACH(QGraphicsItem * item, scene->items()) {
                    scene->sendEvent(item, &event);
                }
            }

            setViewSizeAndRotation(*notification->view, *notification->infoBanner);
        }
    }
}

void DuiCompositorNotificationSink::setViewSizeAndRotation(QGraphicsView &view, const DuiInfoBanner &infoBanner)
{
    QTransform transform;
    transform.rotate(MainWindow::instance()->orientationAngle());
    view.setTransform(transform);
    if (MainWindow::instance()->orientation() == Dui::Landscape) {
        view.setFixedSize(infoBanner.preferredSize().width(), infoBanner.preferredSize().height());
    } else {
        view.setFixedSize(infoBanner.preferredSize().height(), infoBanner.preferredSize().width());
    }
}
<commit_msg>Changes: Add a hint not to style the plain QGraphicsView<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of duihome.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QGraphicsScene>
#include <QTimer>
#include <DuiInfoBanner>
#include <DuiWindow>
#include <DuiScene>
#include <DuiSceneManager>
#include <DuiOrientationChangeEvent>
#include "homeapplication.h"
#include "mainwindow.h"
#include "notificationmanager.h"
#include "duicompositornotificationsink.h"
#include "notificationwidgetparameterfactory.h"
#include "x11wrapper.h"

DuiCompositorNotificationSink::DuiCompositorNotificationSink() :
    orientationChangeSignalConnected(false)
{
    // Get X11 Atoms for different window types
    Display *dpy = QX11Info::display();
    windowTypeAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
    windowTypeDesktopAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
    clientListStackingAtom = X11Wrapper::XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
}

DuiCompositorNotificationSink::~DuiCompositorNotificationSink()
{
    // Destroy the remaining notifications
    foreach(uint id, idToNotification.keys()) {
        notificationDone(id, false);
    }
}

void DuiCompositorNotificationSink::addNotification(const Notification &notification)
{
    if (!canAddNotification(notification)) return;

    if (!orientationChangeSignalConnected) {
        // Get informed about orientation changes
        connect(MainWindow::instance(), SIGNAL(orientationChangeFinished(const Dui::Orientation &)), this, SLOT(rotateInfoBanners(const Dui::Orientation &)));
        orientationChangeSignalConnected = true;
    }

    if (idToNotification.contains(notification.notificationId())) {
        // The notification already exists so update it
        updateNotification(notification);
    } else if (!isDesktopWindowOnTop()) {
        // If the desktop window is not on top show an info banner
        // Create a new toplevel window for the info banner
        QGraphicsScene *scene = new QGraphicsScene;
        QGraphicsView *view = new QGraphicsView(scene);
        view->setProperty("NoDuiStyle", true);
        view->setFrameStyle(0);
        view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        view->setAttribute(Qt::WA_X11NetWmWindowTypeNotification);

        // Create a timer for the info banner; make it a child of the window so it is destroyed automatically
        QTimer *timer = new QTimer(view);
        timer->setSingleShot(true);
        connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));
        timer->setProperty("notificationId", notification.notificationId());

        // Create info banner widget
        DuiInfoBanner *infoBanner = createInfoBanner(notification);
        infoBanner->setManagedManually(true);

        // Rotate the view to the current orientation and make the view as big as the info banner and
        setViewSizeAndRotation(*view, *infoBanner);
        view->show();

        // Add the info banner widget to the scene
        scene->addItem(infoBanner);

        // Keep track of the mapping between IDs and private notification information classes
        idToNotification.insert(notification.notificationId(), new DuiCompositorNotificationSinkNotification(view, timer, infoBanner));

        // Make the info banner disappear after the timeout
        timer->start(notification.timeout());
    }
}

void DuiCompositorNotificationSink::updateNotification(const Notification &notification)
{
    DuiCompositorNotificationSinkNotification *sinkNotification = idToNotification.value(notification.notificationId());

    if (sinkNotification != NULL && sinkNotification->infoBanner != NULL) {
        // Update the info banner widget
        sinkNotification->infoBanner->setImageID(notification.parameters().value(NotificationWidgetParameterFactory::imageIdKey()).toString());
        sinkNotification->infoBanner->setBodyText(notification.parameters().value(NotificationWidgetParameterFactory::bodyKey()).toString());
        sinkNotification->infoBanner->setIconID(determineIconId(notification.parameters()));

        // Update the info banner's actions
        updateActions(sinkNotification->infoBanner, notification.parameters());
    }
}

void DuiCompositorNotificationSink::removeNotification(uint notificationId)
{
    notificationDone(notificationId, false);
}

void DuiCompositorNotificationSink::notificationDone(uint notificationId, bool notificationIdInUse)
{
    DuiCompositorNotificationSinkNotification *sinkNotification = idToNotification.take(notificationId);
    if (sinkNotification != NULL) {
        // Destroy the notification window immediately; this also destroys the timer
        QGraphicsScene *scene = sinkNotification->view->scene();
        delete sinkNotification->view;

        // Remove the info banner from the scene and destroy it
        scene->removeItem(sinkNotification->infoBanner);
        delete sinkNotification->infoBanner;

        // Destroy the scene and the notification information
        delete scene;
        delete sinkNotification;
    }

    if (notificationIdInUse) {
        idToNotification.insert(notificationId, NULL);
    }
}

void DuiCompositorNotificationSink::timeout()
{
    QTimer *timer = qobject_cast<QTimer *>(sender());

    if (timer != NULL) {
        // Get the notification ID from the timer
        bool ok = false;
        uint notificationId = timer->property("notificationId").toUInt(&ok);

        if (ok) {
            // Remove the notification
            notificationDone(notificationId, true);
        }
    }
}

DuiCompositorNotificationSink::DuiCompositorNotificationSinkNotification::DuiCompositorNotificationSinkNotification(QGraphicsView *view, QTimer *timer, DuiInfoBanner *infoBanner) :
    view(view),
    timer(timer),
    infoBanner(infoBanner)
{
}

DuiCompositorNotificationSink::DuiCompositorNotificationSinkNotification::~DuiCompositorNotificationSinkNotification()
{
}

bool DuiCompositorNotificationSink::isDesktopWindowOnTop()
{
    bool desktopOnTop = false;

    // Get a list of all windows in their stacking order
    Display *dpy = QX11Info::display();
    Atom actualType;
    int actualFormat;
    unsigned long numWindowItems, bytesLeft;
    unsigned char *windowData = NULL;
    int result = X11Wrapper::XGetWindowProperty(dpy, DefaultRootWindow(dpy), clientListStackingAtom, 0, 0x7fffffff, False, XA_WINDOW,
                 &actualType, &actualFormat, &numWindowItems, &bytesLeft, &windowData);

    if (result == Success && windowData != None && numWindowItems > 0) {
        Window *wins = (Window *)windowData;
        unsigned char *typeData = NULL;
        unsigned long numTypeItems;

        // Get the window type
        result = X11Wrapper::XGetWindowProperty(dpy, wins[numWindowItems - 1], windowTypeAtom, 0L, 16L, False, XA_ATOM,
                                                &actualType, &actualFormat, &numTypeItems, &bytesLeft, &typeData);

        if (result == Success) {
            Atom *type = (Atom *)typeData;

            // Check if the types list includes desktop
            for (unsigned int n = 0; n < numTypeItems; n++) {
                if (type[n] == windowTypeDesktopAtom) {
                    desktopOnTop = true;
                    break;
                }
            }

            X11Wrapper::XFree(typeData);
        }

        X11Wrapper::XFree(wins);
    }

    return desktopOnTop;
}

void DuiCompositorNotificationSink::rotateInfoBanners(const Dui::Orientation &orientation)
{
    foreach(DuiCompositorNotificationSinkNotification * notification, idToNotification.values()) {
        // Rotate the views of all existing notifications to the current orientation and resize their sizes accordingly
        if (notification != NULL && notification->view != NULL && notification->infoBanner != NULL) {
            QGraphicsScene *scene = notification->view->scene();
            if (scene != NULL) {
                // Notify each item on the notification view's scene about the new orientation
                DuiOrientationChangeEvent event(orientation);
                Q_FOREACH(QGraphicsItem * item, scene->items()) {
                    scene->sendEvent(item, &event);
                }
            }

            setViewSizeAndRotation(*notification->view, *notification->infoBanner);
        }
    }
}

void DuiCompositorNotificationSink::setViewSizeAndRotation(QGraphicsView &view, const DuiInfoBanner &infoBanner)
{
    QTransform transform;
    transform.rotate(MainWindow::instance()->orientationAngle());
    view.setTransform(transform);
    if (MainWindow::instance()->orientation() == Dui::Landscape) {
        view.setFixedSize(infoBanner.preferredSize().width(), infoBanner.preferredSize().height());
    } else {
        view.setFixedSize(infoBanner.preferredSize().height(), infoBanner.preferredSize().width());
    }
}
<|endoftext|>


<commit_before>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file observation_density.hpp
 * \date June 2015
 * \author Manuel Wuthrich (manuel.wuthrich@gmail.com)
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__MODEL__OBSERVATION__OBSERVATION_DENSITY_HPP
#define FL__MODEL__OBSERVATION__OBSERVATION_DENSITY_HPP

#include <fl/util/traits.hpp>

namespace fl
{

template <
    typename Obsrv,
    typename State
>
class ObservationDensity
{
public:
    /**
     *
     */

    /// \todo should add the unnormalized log probability interface
    virtual FloatingPoint log_probability(const Obsrv& obsrv,
                                          const State& state) const = 0;

    virtual FloatingPoint probability(const Obsrv& obsrv,
                                      const State& state) const
    {
        return std::exp(log_probability(obsrv, state));
    }

    virtual Eigen::Array<FloatingPoint, Eigen::Dynamic, 1> log_probabilities(
        const Obsrv& obsrv,
        const Eigen::Array<State, Eigen::Dynamic, 1>& states)
    {
        Eigen::Array<FloatingPoint, Eigen::Dynamic, 1> probs (states.size());

        for (int i = 0; i < states.size(); ++i)
        {
            probs[i] = log_probability(obsrv, states[i]);
        }

        return probs;
    }

    virtual Eigen::Array<FloatingPoint, Eigen::Dynamic, 1> probabilities(
        const Obsrv& obsrv,
        const Eigen::Array<State, Eigen::Dynamic, 1>& states)
    {
        return log_probabilities(obsrv, states).exp();
    }

    /**
     * \return Dimension of the state variable $\f$x\f$
     */
    virtual int state_dimension() const = 0;

    /**
     * \return Dimension of the measurement \f$h(x, w)\f$
     */
    virtual int obsrv_dimension() const = 0;
};

}

#endif
<commit_msg>Model defines StateArray and ValueArray for vectorized evaluations<commit_after>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file observation_density.hpp
 * \date June 2015
 * \author Manuel Wuthrich (manuel.wuthrich@gmail.com)
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__MODEL__OBSERVATION__OBSERVATION_DENSITY_HPP
#define FL__MODEL__OBSERVATION__OBSERVATION_DENSITY_HPP

#include <fl/util/types.hpp>
#include <fl/util/traits.hpp>

namespace fl
{

template <
    typename Obsrv,
    typename State,
    int BatchSize = Eigen::Dynamic
>
class ObservationDensity
{
public:
    typedef Eigen::Array<State, BatchSize, 1 > StateArray;
    typedef Eigen::Array<FloatingPoint, BatchSize, 1 > ValueArray;

public:
    /// \todo should add the unnormalized log probability interface

    virtual FloatingPoint log_probability(const Obsrv& obsrv,
                                          const State& state) const = 0;

    /**
     * \return Dimension of the state variable $\f$x\f$
     */
    virtual int state_dimension() const = 0;

    /**
     * \return Dimension of the measurement \f$h(x, w)\f$
     */
    virtual int obsrv_dimension() const = 0;

    virtual FloatingPoint probability(const Obsrv& obsrv,
                                      const State& state) const
    {
        return std::exp(log_probability(obsrv, state));
    }

    virtual ValueArray log_probabilities(const Obsrv& obsrv,
                                         const StateArray& states)
    {
        auto probs = ValueArray(states.size());

        for (int i = 0; i < states.size(); ++i)
        {
            probs[i] = log_probability(obsrv, states[i]);
        }

        return probs;
    }

    virtual ValueArray probabilities(const Obsrv& obsrv,
                                     const StateArray& states)
    {
        return log_probabilities(obsrv, states).exp();
    }
};

}

#endif
<|endoftext|>