<commit_before>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef DATABASE_HH_
#define DATABASE_HH_

#include "dht/i_partitioner.hh"
#include "locator/abstract_replication_strategy.hh"
#include "core/sstring.hh"
#include "core/shared_ptr.hh"
#include "net/byteorder.hh"
#include "utils/UUID.hh"
#include "utils/hash.hh"
#include "db_clock.hh"
#include "gc_clock.hh"
#include "core/distributed.hh"
#include <functional>
#include <cstdint>
#include <unordered_map>
#include <map>
#include <set>
#include <iostream>
#include <boost/functional/hash.hpp>
#include <experimental/optional>
#include <string.h>
#include "types.hh"
#include "compound.hh"
#include "core/future.hh"
#include "cql3/column_specification.hh"
#include <limits>
#include <cstddef>
#include "schema.hh"
#include "timestamp.hh"
#include "tombstone.hh"
#include "atomic_cell.hh"
#include "query-request.hh"
#include "query-result.hh"
#include "keys.hh"
#include "mutation.hh"
#include "memtable.hh"
#include <list>

class frozen_mutation;

namespace sstables {

class sstable;

}

namespace db {
template<typename T>
class serializer;

class commitlog;
class config;
}

class column_family {
public:
    struct config {
        sstring datadir;
        bool enable_disk_writes = true;
        bool enable_disk_reads = true;
    };
private:
    schema_ptr _schema;
    config _config;
    using memtable_list = std::vector<lw_shared_ptr<memtable>>;
    lw_shared_ptr<memtable_list> _memtables;
    // generation -> sstable. Ordered by key so we can easily get the most recent.
    using sstable_list = std::map<unsigned long, lw_shared_ptr<sstables::sstable>>;
    lw_shared_ptr<sstable_list> _sstables;
    unsigned _sstable_generation = 1;
    unsigned _mutation_count = 0;
private:
    void add_sstable(sstables::sstable&& sstable);
    void add_memtable();
    memtable& active_memtable() { return *_memtables->back(); }
    struct merge_comparator;
public:
    // Queries can be satisfied from multiple data sources, so they are returned
    // as temporaries.
    //
    // FIXME: in case a query is satisfied from a single memtable, avoid a copy
    using const_mutation_partition_ptr = std::unique_ptr<const mutation_partition>;
    using const_row_ptr = std::unique_ptr<const row>;
public:
    column_family(schema_ptr schema, config cfg);
    column_family(column_family&&);
    ~column_family();
    schema_ptr schema() const { return _schema; }
    future<const_mutation_partition_ptr> find_partition(const dht::decorated_key& key) const;
    future<const_mutation_partition_ptr> find_partition_slow(const partition_key& key) const;
    future<const_row_ptr> find_row(const dht::decorated_key& partition_key, clustering_key clustering_key) const;
    void apply(const frozen_mutation& m);
    void apply(const mutation& m);
    // Returns at most "cmd.limit" rows
    future<lw_shared_ptr<query::result>> query(const query::read_command& cmd) const;

    future<> populate(sstring datadir);
    void seal_active_memtable();
private:
    // Iterate over all partitions.  Protocol is the same as std::all_of(),
    // so that iteration can be stopped by returning false.
    // Func signature: bool (const decorated_key& dk, const mutation_partition& mp)
    template <typename Func>
    future<bool> for_all_partitions(Func&& func) const;
    future<> probe_file(sstring sstdir, sstring fname);
    void seal_on_overflow();
public:
    // Iterate over all partitions.  Protocol is the same as std::all_of(),
    // so that iteration can be stopped by returning false.
    future<bool> for_all_partitions_slow(std::function<bool (const dht::decorated_key&, const mutation_partition&)> func) const;

    friend std::ostream& operator<<(std::ostream& out, const column_family& cf);
};

class user_types_metadata {
    std::unordered_map<bytes, user_type> _user_types;
public:
    user_type get_type(bytes name) const {
        return _user_types.at(name);
    }
    const std::unordered_map<bytes, user_type>& get_all_types() const {
        return _user_types;
    }
    void add_type(user_type type) {
        auto i = _user_types.find(type->_name);
        assert(i == _user_types.end() || type->is_compatible_with(*i->second));
        _user_types[type->_name] = std::move(type);
    }
    void remove_type(user_type type) {
        _user_types.erase(type->_name);
    }
};

class keyspace_metadata final {
    sstring _name;
    sstring _strategy_name;
    std::unordered_map<sstring, sstring> _strategy_options;
    std::unordered_map<sstring, schema_ptr> _cf_meta_data;
    bool _durable_writes;
    lw_shared_ptr<user_types_metadata> _user_types;
public:
    keyspace_metadata(sstring name,
                 sstring strategy_name,
                 std::unordered_map<sstring, sstring> strategy_options,
                 bool durable_writes,
                 std::vector<schema_ptr> cf_defs = std::vector<schema_ptr>{},
                 lw_shared_ptr<user_types_metadata> user_types = make_lw_shared<user_types_metadata>())
        : _name{std::move(name)}
        , _strategy_name{strategy_name.empty() ? "NetworkTopologyStrategy" : strategy_name}
        , _strategy_options{std::move(strategy_options)}
        , _durable_writes{durable_writes}
        , _user_types{std::move(user_types)}
    {
        for (auto&& s : cf_defs) {
            _cf_meta_data.emplace(s->cf_name(), s);
        }
    }
    static lw_shared_ptr<keyspace_metadata>
    new_keyspace(sstring name,
                 sstring strategy_name,
                 std::unordered_map<sstring, sstring> options,
                 bool durables_writes,
                 std::vector<schema_ptr> cf_defs = std::vector<schema_ptr>{})
    {
        return ::make_lw_shared<keyspace_metadata>(name, strategy_name, options, durables_writes, cf_defs);
    }
    const sstring& name() const {
        return _name;
    }
    const sstring& strategy_name() const {
        return _strategy_name;
    }
    const std::unordered_map<sstring, sstring>& strategy_options() const {
        return _strategy_options;
    }
    const std::unordered_map<sstring, schema_ptr>& cf_meta_data() const {
        return _cf_meta_data;
    }
    bool durable_writes() const {
        return _durable_writes;
    }
    const lw_shared_ptr<user_types_metadata>& user_types() const {
        return _user_types;
    }
    void add_column_family(const schema_ptr& s) {
        _cf_meta_data.emplace(s->cf_name(), s);
    }
};

class keyspace {
public:
    struct config {
        sstring datadir;
        bool enable_disk_reads = true;
        bool enable_disk_writes = true;
    };
private:
    std::unique_ptr<locator::abstract_replication_strategy> _replication_strategy;
    lw_shared_ptr<keyspace_metadata> _metadata;
    config _config;
public:
    explicit keyspace(lw_shared_ptr<keyspace_metadata> metadata, config cfg)
        : _metadata(std::move(metadata))
        , _config(std::move(cfg))
    {}
    user_types_metadata _user_types;
    const lw_shared_ptr<keyspace_metadata>& metadata() const {
        return _metadata;
    }
    void create_replication_strategy();
    locator::abstract_replication_strategy& get_replication_strategy();
    column_family::config make_column_family_config(const schema& s) const;
    future<> make_directory_for_column_family(const sstring& name, utils::UUID uuid);
    void add_column_family(const schema_ptr& s) {
        _metadata->add_column_family(s);
    }
private:
    sstring column_family_directory(const sstring& name, utils::UUID uuid) const;
};

class no_such_keyspace : public std::runtime_error {
public:
    using runtime_error::runtime_error;
};

class no_such_column_family : public std::runtime_error {
public:
    using runtime_error::runtime_error;
};

// Policy for distributed<database>:
//   broadcast metadata writes
//   local metadata reads
//   use shard_of() for data

class database {
    std::unordered_map<sstring, keyspace> _keyspaces;
    std::unordered_map<utils::UUID, column_family> _column_families;
    std::unordered_map<std::pair<sstring, sstring>, utils::UUID, utils::tuple_hash> _ks_cf_to_uuid;
    std::unique_ptr<db::commitlog> _commitlog;
    std::unique_ptr<db::config> _cfg;

    future<> init_commitlog();
    future<> apply_in_memory(const frozen_mutation&);
    future<> populate(sstring datadir);
public:
    database();
    database(const db::config&);
    database(database&&) = default;
    ~database();

    db::commitlog* commitlog() const {
        return _commitlog.get();
    }

    future<> init_from_data_directory();

    // but see: create_keyspace(distributed<database>&, sstring)
    void add_keyspace(sstring name, keyspace k);
    /** Adds cf with auto-generated UUID. */
    void add_column_family(column_family&&);
    void add_column_family(const utils::UUID&, column_family&&);

    /* throws std::out_of_range if missing */
    const utils::UUID& find_uuid(const sstring& ks, const sstring& cf) const throw (std::out_of_range);
    const utils::UUID& find_uuid(const schema_ptr&) const throw (std::out_of_range);

    /* below, find* throws no_such_<type> on fail */
    keyspace& find_or_create_keyspace(const lw_shared_ptr<keyspace_metadata>&);
    keyspace& find_keyspace(const sstring& name) throw (no_such_keyspace);
    const keyspace& find_keyspace(const sstring& name) const throw (no_such_keyspace);
    bool has_keyspace(const sstring& name) const;
    void update_keyspace(const sstring& name);
    void drop_keyspace(const sstring& name);
    column_family& find_column_family(const sstring& ks, const sstring& name) throw (no_such_column_family);
    const column_family& find_column_family(const sstring& ks, const sstring& name) const throw (no_such_column_family);
    column_family& find_column_family(const utils::UUID&) throw (no_such_column_family);
    const column_family& find_column_family(const utils::UUID&) const throw (no_such_column_family);
    column_family& find_column_family(const schema_ptr&) throw (no_such_column_family);
    const column_family& find_column_family(const schema_ptr&) const throw (no_such_column_family);
    schema_ptr find_schema(const sstring& ks_name, const sstring& cf_name) const throw (no_such_column_family);
    schema_ptr find_schema(const utils::UUID&) const throw (no_such_column_family);
    future<> stop();
    unsigned shard_of(const dht::token& t);
    unsigned shard_of(const mutation& m);
    unsigned shard_of(const frozen_mutation& m);
    future<lw_shared_ptr<query::result>> query(const query::read_command& cmd);
    future<> apply(const frozen_mutation&);
    keyspace::config make_keyspace_config(const keyspace_metadata& ksm) const;
    friend std::ostream& operator<<(std::ostream& out, const database& db);
    friend future<> create_keyspace(distributed<database>&, const lw_shared_ptr<keyspace_metadata>&);
};

// Creates a keyspace.  Keyspaces have a non-sharded
// component (the directory), so a global function is needed.
future<> create_keyspace(distributed<database>& db, const keyspace_metadata&);

// FIXME: stub
class secondary_index_manager {};

inline
void
column_family::apply(const mutation& m) {
    active_memtable().apply(m);
    seal_on_overflow();
}

inline
void
column_family::seal_on_overflow() {
    // FIXME: something better
    if (++_mutation_count == 10000) {
        _mutation_count = 0;
        seal_active_memtable();
    }
}

inline
void
column_family::apply(const frozen_mutation& m) {
    active_memtable().apply(m);
    seal_on_overflow();
}

#endif /* DATABASE_HH_ */
<commit_msg>db: add getter for database::_keyspaces<commit_after>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef DATABASE_HH_
#define DATABASE_HH_

#include "dht/i_partitioner.hh"
#include "locator/abstract_replication_strategy.hh"
#include "core/sstring.hh"
#include "core/shared_ptr.hh"
#include "net/byteorder.hh"
#include "utils/UUID.hh"
#include "utils/hash.hh"
#include "db_clock.hh"
#include "gc_clock.hh"
#include "core/distributed.hh"
#include <functional>
#include <cstdint>
#include <unordered_map>
#include <map>
#include <set>
#include <iostream>
#include <boost/functional/hash.hpp>
#include <experimental/optional>
#include <string.h>
#include "types.hh"
#include "compound.hh"
#include "core/future.hh"
#include "cql3/column_specification.hh"
#include <limits>
#include <cstddef>
#include "schema.hh"
#include "timestamp.hh"
#include "tombstone.hh"
#include "atomic_cell.hh"
#include "query-request.hh"
#include "query-result.hh"
#include "keys.hh"
#include "mutation.hh"
#include "memtable.hh"
#include <list>

class frozen_mutation;

namespace sstables {

class sstable;

}

namespace db {
template<typename T>
class serializer;

class commitlog;
class config;
}

class column_family {
public:
    struct config {
        sstring datadir;
        bool enable_disk_writes = true;
        bool enable_disk_reads = true;
    };
private:
    schema_ptr _schema;
    config _config;
    using memtable_list = std::vector<lw_shared_ptr<memtable>>;
    lw_shared_ptr<memtable_list> _memtables;
    // generation -> sstable. Ordered by key so we can easily get the most recent.
    using sstable_list = std::map<unsigned long, lw_shared_ptr<sstables::sstable>>;
    lw_shared_ptr<sstable_list> _sstables;
    unsigned _sstable_generation = 1;
    unsigned _mutation_count = 0;
private:
    void add_sstable(sstables::sstable&& sstable);
    void add_memtable();
    memtable& active_memtable() { return *_memtables->back(); }
    struct merge_comparator;
public:
    // Queries can be satisfied from multiple data sources, so they are returned
    // as temporaries.
    //
    // FIXME: in case a query is satisfied from a single memtable, avoid a copy
    using const_mutation_partition_ptr = std::unique_ptr<const mutation_partition>;
    using const_row_ptr = std::unique_ptr<const row>;
public:
    column_family(schema_ptr schema, config cfg);
    column_family(column_family&&);
    ~column_family();
    schema_ptr schema() const { return _schema; }
    future<const_mutation_partition_ptr> find_partition(const dht::decorated_key& key) const;
    future<const_mutation_partition_ptr> find_partition_slow(const partition_key& key) const;
    future<const_row_ptr> find_row(const dht::decorated_key& partition_key, clustering_key clustering_key) const;
    void apply(const frozen_mutation& m);
    void apply(const mutation& m);
    // Returns at most "cmd.limit" rows
    future<lw_shared_ptr<query::result>> query(const query::read_command& cmd) const;

    future<> populate(sstring datadir);
    void seal_active_memtable();
private:
    // Iterate over all partitions.  Protocol is the same as std::all_of(),
    // so that iteration can be stopped by returning false.
    // Func signature: bool (const decorated_key& dk, const mutation_partition& mp)
    template <typename Func>
    future<bool> for_all_partitions(Func&& func) const;
    future<> probe_file(sstring sstdir, sstring fname);
    void seal_on_overflow();
public:
    // Iterate over all partitions.  Protocol is the same as std::all_of(),
    // so that iteration can be stopped by returning false.
    future<bool> for_all_partitions_slow(std::function<bool (const dht::decorated_key&, const mutation_partition&)> func) const;

    friend std::ostream& operator<<(std::ostream& out, const column_family& cf);
};

class user_types_metadata {
    std::unordered_map<bytes, user_type> _user_types;
public:
    user_type get_type(bytes name) const {
        return _user_types.at(name);
    }
    const std::unordered_map<bytes, user_type>& get_all_types() const {
        return _user_types;
    }
    void add_type(user_type type) {
        auto i = _user_types.find(type->_name);
        assert(i == _user_types.end() || type->is_compatible_with(*i->second));
        _user_types[type->_name] = std::move(type);
    }
    void remove_type(user_type type) {
        _user_types.erase(type->_name);
    }
};

class keyspace_metadata final {
    sstring _name;
    sstring _strategy_name;
    std::unordered_map<sstring, sstring> _strategy_options;
    std::unordered_map<sstring, schema_ptr> _cf_meta_data;
    bool _durable_writes;
    lw_shared_ptr<user_types_metadata> _user_types;
public:
    keyspace_metadata(sstring name,
                 sstring strategy_name,
                 std::unordered_map<sstring, sstring> strategy_options,
                 bool durable_writes,
                 std::vector<schema_ptr> cf_defs = std::vector<schema_ptr>{},
                 lw_shared_ptr<user_types_metadata> user_types = make_lw_shared<user_types_metadata>())
        : _name{std::move(name)}
        , _strategy_name{strategy_name.empty() ? "NetworkTopologyStrategy" : strategy_name}
        , _strategy_options{std::move(strategy_options)}
        , _durable_writes{durable_writes}
        , _user_types{std::move(user_types)}
    {
        for (auto&& s : cf_defs) {
            _cf_meta_data.emplace(s->cf_name(), s);
        }
    }
    static lw_shared_ptr<keyspace_metadata>
    new_keyspace(sstring name,
                 sstring strategy_name,
                 std::unordered_map<sstring, sstring> options,
                 bool durables_writes,
                 std::vector<schema_ptr> cf_defs = std::vector<schema_ptr>{})
    {
        return ::make_lw_shared<keyspace_metadata>(name, strategy_name, options, durables_writes, cf_defs);
    }
    const sstring& name() const {
        return _name;
    }
    const sstring& strategy_name() const {
        return _strategy_name;
    }
    const std::unordered_map<sstring, sstring>& strategy_options() const {
        return _strategy_options;
    }
    const std::unordered_map<sstring, schema_ptr>& cf_meta_data() const {
        return _cf_meta_data;
    }
    bool durable_writes() const {
        return _durable_writes;
    }
    const lw_shared_ptr<user_types_metadata>& user_types() const {
        return _user_types;
    }
    void add_column_family(const schema_ptr& s) {
        _cf_meta_data.emplace(s->cf_name(), s);
    }
};

class keyspace {
public:
    struct config {
        sstring datadir;
        bool enable_disk_reads = true;
        bool enable_disk_writes = true;
    };
private:
    std::unique_ptr<locator::abstract_replication_strategy> _replication_strategy;
    lw_shared_ptr<keyspace_metadata> _metadata;
    config _config;
public:
    explicit keyspace(lw_shared_ptr<keyspace_metadata> metadata, config cfg)
        : _metadata(std::move(metadata))
        , _config(std::move(cfg))
    {}
    user_types_metadata _user_types;
    const lw_shared_ptr<keyspace_metadata>& metadata() const {
        return _metadata;
    }
    void create_replication_strategy();
    locator::abstract_replication_strategy& get_replication_strategy();
    column_family::config make_column_family_config(const schema& s) const;
    future<> make_directory_for_column_family(const sstring& name, utils::UUID uuid);
    void add_column_family(const schema_ptr& s) {
        _metadata->add_column_family(s);
    }
private:
    sstring column_family_directory(const sstring& name, utils::UUID uuid) const;
};

class no_such_keyspace : public std::runtime_error {
public:
    using runtime_error::runtime_error;
};

class no_such_column_family : public std::runtime_error {
public:
    using runtime_error::runtime_error;
};

// Policy for distributed<database>:
//   broadcast metadata writes
//   local metadata reads
//   use shard_of() for data

class database {
    std::unordered_map<sstring, keyspace> _keyspaces;
    std::unordered_map<utils::UUID, column_family> _column_families;
    std::unordered_map<std::pair<sstring, sstring>, utils::UUID, utils::tuple_hash> _ks_cf_to_uuid;
    std::unique_ptr<db::commitlog> _commitlog;
    std::unique_ptr<db::config> _cfg;

    future<> init_commitlog();
    future<> apply_in_memory(const frozen_mutation&);
    future<> populate(sstring datadir);
public:
    database();
    database(const db::config&);
    database(database&&) = default;
    ~database();

    db::commitlog* commitlog() const {
        return _commitlog.get();
    }

    future<> init_from_data_directory();

    // but see: create_keyspace(distributed<database>&, sstring)
    void add_keyspace(sstring name, keyspace k);
    /** Adds cf with auto-generated UUID. */
    void add_column_family(column_family&&);
    void add_column_family(const utils::UUID&, column_family&&);

    /* throws std::out_of_range if missing */
    const utils::UUID& find_uuid(const sstring& ks, const sstring& cf) const throw (std::out_of_range);
    const utils::UUID& find_uuid(const schema_ptr&) const throw (std::out_of_range);

    /* below, find* throws no_such_<type> on fail */
    keyspace& find_or_create_keyspace(const lw_shared_ptr<keyspace_metadata>&);
    keyspace& find_keyspace(const sstring& name) throw (no_such_keyspace);
    const keyspace& find_keyspace(const sstring& name) const throw (no_such_keyspace);
    bool has_keyspace(const sstring& name) const;
    void update_keyspace(const sstring& name);
    void drop_keyspace(const sstring& name);
    const auto& keyspaces() const { return _keyspaces; }
    column_family& find_column_family(const sstring& ks, const sstring& name) throw (no_such_column_family);
    const column_family& find_column_family(const sstring& ks, const sstring& name) const throw (no_such_column_family);
    column_family& find_column_family(const utils::UUID&) throw (no_such_column_family);
    const column_family& find_column_family(const utils::UUID&) const throw (no_such_column_family);
    column_family& find_column_family(const schema_ptr&) throw (no_such_column_family);
    const column_family& find_column_family(const schema_ptr&) const throw (no_such_column_family);
    schema_ptr find_schema(const sstring& ks_name, const sstring& cf_name) const throw (no_such_column_family);
    schema_ptr find_schema(const utils::UUID&) const throw (no_such_column_family);
    future<> stop();
    unsigned shard_of(const dht::token& t);
    unsigned shard_of(const mutation& m);
    unsigned shard_of(const frozen_mutation& m);
    future<lw_shared_ptr<query::result>> query(const query::read_command& cmd);
    future<> apply(const frozen_mutation&);
    keyspace::config make_keyspace_config(const keyspace_metadata& ksm) const;
    friend std::ostream& operator<<(std::ostream& out, const database& db);
    friend future<> create_keyspace(distributed<database>&, const lw_shared_ptr<keyspace_metadata>&);
};

// Creates a keyspace.  Keyspaces have a non-sharded
// component (the directory), so a global function is needed.
future<> create_keyspace(distributed<database>& db, const keyspace_metadata&);

// FIXME: stub
class secondary_index_manager {};

inline
void
column_family::apply(const mutation& m) {
    active_memtable().apply(m);
    seal_on_overflow();
}

inline
void
column_family::seal_on_overflow() {
    // FIXME: something better
    if (++_mutation_count == 10000) {
        _mutation_count = 0;
        seal_active_memtable();
    }
}

inline
void
column_family::apply(const frozen_mutation& m) {
    active_memtable().apply(m);
    seal_on_overflow();
}

#endif /* DATABASE_HH_ */
<|endoftext|>


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

#include <fstream>
#include "rtkGeometricPhantomFileReader.h"

namespace rtk
{
bool GeometricPhantomFileReader::Config(const std::string ConfigFile )
{
  const char *       search_fig = "Ellipsoid"; // Set search pattern
  size_t             offset = 0;
  std::string        line;
  std::ifstream      myFile;

  myFile.open( ConfigFile.c_str() );
  if ( !myFile.is_open() )
    {
    itkGenericExceptionMacro("Error opening File");
    return false;
    }

  while ( !myFile.eof() )
    {
    getline(myFile, line);
    if ( ( offset = line.find(search_fig, 0) ) != std::string::npos ) //Ellipsoid
                                                                      // found
      {
      const std::string parameterNames[8] = { "x", "y", "z", "A", "B", "C", "beta", "gray" };
      VectorType parameters;
      for ( int j = 0; j < 8; j++ )
        {
        double val = 0.;
        if ( ( offset = line.find(parameterNames[j], 0) ) != std::string::npos )
          {
          offset += parameterNames[j].length()+1;
          std::string s = line.substr(offset,line.length()-offset);
          std::istringstream ss(s);
          ss >> val;
          //Saving all parameters for each ellipsoid
          }
        parameters.push_back(val);
        }
      m_Fig.push_back(parameters);
      }
    }
  myFile.close();
  return true;
}

GeometricPhantomFileReader::VectorOfVectorType GeometricPhantomFileReader::GetFig ()
{
  itkDebugMacro("returning Fig.");
  return this->m_Fig;
}

void GeometricPhantomFileReader::SetFig (const VectorOfVectorType _arg)
{
  itkDebugMacro("setting Fig");
  if (this->m_Fig != _arg)
    {
    this->m_Fig = _arg;
    this->Modified();
    }
}

} // namespace rtk
<commit_msg>Modified phantom config file reader due to differences with Kak and Slaney book<commit_after>/*=========================================================================
 *
 *  Copyright RTK Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include <fstream>
#include "rtkGeometricPhantomFileReader.h"

namespace rtk
{
bool GeometricPhantomFileReader::Config(const std::string ConfigFile )
{
  const char *       search_fig = "Ellipsoid"; // Set search pattern
  size_t             offset = 0;
  std::string        line;
  std::ifstream      myFile;

  myFile.open( ConfigFile.c_str() );
  if ( !myFile.is_open() )
    {
    itkGenericExceptionMacro("Error opening File");
    return false;
    }

  while ( !myFile.eof() )
    {
    getline(myFile, line);
    if ( ( offset = line.find(search_fig, 0) ) != std::string::npos ) //Ellipsoid
                                                                      // found
      {
      const std::string parameterNames[8] = { "A", "B", "C", "x", "y", "z", "beta", "gray" };
      VectorType parameters;
      for ( int j = 0; j < 8; j++ )
        {
        double val = 0.;
        if ( ( offset = line.find(parameterNames[j], 0) ) != std::string::npos )
          {
          offset += parameterNames[j].length()+1;
          std::string s = line.substr(offset,line.length()-offset);
          std::istringstream ss(s);
          ss >> val;
          //Saving all parameters for each ellipsoid
          }
        parameters.push_back(val);
        }
      m_Fig.push_back(parameters);
      }
    }
  myFile.close();
  return true;
}

GeometricPhantomFileReader::VectorOfVectorType GeometricPhantomFileReader::GetFig ()
{
  itkDebugMacro("returning Fig.");
  return this->m_Fig;
}

void GeometricPhantomFileReader::SetFig (const VectorOfVectorType _arg)
{
  itkDebugMacro("setting Fig");
  if (this->m_Fig != _arg)
    {
    this->m_Fig = _arg;
    this->Modified();
    }
}

} // namespace rtk
<|endoftext|>


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

#include <fstream>
#include "rtkGeometricPhantomFileReader.h"

namespace rtk
{
bool GeometricPhantomFileReader::Config(const std::string ConfigFile )
{
  const char *       search_fig = "Ellipsoid"; // Set search pattern
  int                offset = 0;
  std::string        line;
  std::ifstream      myFile;

  myFile.open( ConfigFile.c_str() );
  if ( !myFile.is_open() )
    {
    itkGenericExceptionMacro("Error opening File");
    return false;
    }

  while ( !myFile.eof() )
    {
    getline(myFile, line);
    if ( ( offset = line.find(search_fig, 0) ) != std::string::npos ) //Ellipsoid
                                                                      // found
      {
      const std::string parameterNames[8] = { "x", "y", "z", "A", "B", "C", "beta", "gray" };
      VectorType parameters;
      for ( int j = 0; j < 8; j++ )
        {
        double val = 0.;
        if ( ( offset = line.find(parameterNames[j], 0) ) != std::string::npos )
          {
          offset += parameterNames[j].length()+1;
          std::string s = line.substr(offset,line.length()-offset);
          std::istringstream ss(s);
          ss >> val;
          //Saving all parameters for each ellipsoid
          }
        parameters.push_back(val);
        }
      m_Fig.push_back(parameters);
      }
    }
  myFile.close();
  return true;
}

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

#include <fstream>
#include "rtkGeometricPhantomFileReader.h"

namespace rtk
{
bool GeometricPhantomFileReader::Config(const std::string ConfigFile )
{
  const char *       search_fig = "Ellipsoid"; // Set search pattern
  size_t             offset = 0;
  std::string        line;
  std::ifstream      myFile;

  myFile.open( ConfigFile.c_str() );
  if ( !myFile.is_open() )
    {
    itkGenericExceptionMacro("Error opening File");
    return false;
    }

  while ( !myFile.eof() )
    {
    getline(myFile, line);
    if ( ( offset = line.find(search_fig, 0) ) != std::string::npos ) //Ellipsoid
                                                                      // found
      {
      const std::string parameterNames[8] = { "x", "y", "z", "A", "B", "C", "beta", "gray" };
      VectorType parameters;
      for ( int j = 0; j < 8; j++ )
        {
        double val = 0.;
        if ( ( offset = line.find(parameterNames[j], 0) ) != std::string::npos )
          {
          offset += parameterNames[j].length()+1;
          std::string s = line.substr(offset,line.length()-offset);
          std::istringstream ss(s);
          ss >> val;
          //Saving all parameters for each ellipsoid
          }
        parameters.push_back(val);
        }
      m_Fig.push_back(parameters);
      }
    }
  myFile.close();
  return true;
}

} // namespace rtk
<|endoftext|>


<commit_before><commit_msg>testing mask<commit_after><|endoftext|>


<commit_before>/*

*/

#include "lineFollowing.h"

using namespace std;
using namespace cv;

ControlMovements lineFollowingControl() {

  line_main();

  return ControlMovements();
}

void line_main() {
//  printf("Hello, this is Caleb\n");

  VideoCapture cap("../../tests/videos/top_down_4.m4v");
  if (!cap.isOpened())  // check if we succeeded
    return;

  namedWindow("edges", CV_WINDOW_NORMAL);
//  Mat edges;
  for (; ;) {
    Mat mask;
    Mat frame, hsv;
    cap >> frame; // get a new frame from camera

    cvtColor(frame, hsv, CV_BGR2HSV);

    double minH = 30;
    double minS = 0;
    double minV = 240;
    double maxH = 80;
    double maxS = 70;
    double maxV = 255;

    cv::Scalar lower(minH, minS, minV);
    cv::Scalar upper(maxH, maxS, maxV);
    cv::inRange(hsv, lower, upper, mask);

//    bitwise_and(frame, frame, frame, mask);

//    medianBlur(mask, mask, 5);

    erode(mask, mask, Mat(), Point(-1,-1), 20);
    vector <Vec4i> lines;
    HoughLinesP(mask, lines, 1, CV_PI / 180.0, 10, 100, 10);

    printf("Adding in %d lines\n", (int) lines.size());
    for (size_t i = 0; i < lines.size(); i++) {
      Vec4i l = lines[i];
      line(frame, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, CV_AA);
      // break;
    }
//    if (lines.size() < 1) continue;

    imshow("edges", mask);
    if (waitKey(30) >= 0) break;

  }
  // the camera will be deinitialized automatically in VideoCapture destructor
  return;
}
<commit_msg>messing with erode<commit_after>/*

*/

#include "lineFollowing.h"

using namespace std;
using namespace cv;

ControlMovements lineFollowingControl() {

  line_main();

  return ControlMovements();
}

void line_main() {
//  printf("Hello, this is Caleb\n");

  VideoCapture cap("../../tests/videos/top_down_4.m4v");
  if (!cap.isOpened())  // check if we succeeded
    return;

  namedWindow("edges", CV_WINDOW_NORMAL);
//  Mat edges;
  for (; ;) {
    Mat mask;
    Mat frame, hsv;
    cap >> frame; // get a new frame from camera

    cvtColor(frame, hsv, CV_BGR2HSV);

    double minH = 30;
    double minS = 0;
    double minV = 240;
    double maxH = 80;
    double maxS = 70;
    double maxV = 255;

    cv::Scalar lower(minH, minS, minV);
    cv::Scalar upper(maxH, maxS, maxV);
    cv::inRange(hsv, lower, upper, mask);

//    bitwise_and(frame, frame, frame, mask);

//    medianBlur(mask, mask, 5);

    erode(mask, mask, Mat(), Point(-1,-1), 12);
    vector <Vec4i> lines;
    HoughLinesP(mask, lines, 1, CV_PI / 180.0, 10, 100, 10);

    printf("Adding in %d lines\n", (int) lines.size());
    for (size_t i = 0; i < lines.size(); i++) {
      Vec4i l = lines[i];
      line(frame, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, CV_AA);
      // break;
    }
//    if (lines.size() < 1) continue;

    imshow("edges", mask);
    if (waitKey(30) >= 0) break;

  }
  // the camera will be deinitialized automatically in VideoCapture destructor
  return;
}
<|endoftext|>


<commit_before>df6e93d9-ad5c-11e7-9342-ac87a332f658<commit_msg>For bobby to integrate at some point<commit_after>dfcbd4a1-ad5c-11e7-a833-ac87a332f658<|endoftext|>


<commit_before>//    Copyright (c) 2018 Will Wray https://keybase.io/willwray
//
//   Distributed under the Boost Software License, Version 1.0.
//          (http://www.boost.org/LICENSE_1_0.txt)

#pragma once

#include <cstring>
#include <string>
#include <string_view>
#include <typeinfo>
#include <type_traits>

#if __has_include(<cxxabi.h>)
#   include <cxxabi.h>
#   include <cstdlib>
#   include <memory>
#endif

constexpr bool CXXABI
{
#if __has_include(<cxxabi.h>)
    true
#endif
};

/*
  "type_name_rt.hpp": get type names at runtime (hence 'rt')
   ^^^^^^^^^^^^^^^^
   This header defines, in global scope (i.e. not namespace'd):
   (1) A function template type_name_str<T>() for extracting a type's name.
   (2) A variable template type_name_rt<T> initialized to the type's name.
      (also an incomplete class template IdT<T>, an implementation detail.)
   The template type parameter T is mapped to a readable name for the type.
   The work is done at runtime by what is the most standard current method;
   runtime type information (RTTI) and, on CXXABI, a demangle call
   (for compile-time alternatives see type_name_pt or type_name_ct).
   (1) type_name_str<T>()
                   Returns a std::string copy of the demangled typeid name.
                   On each call it does all the work, and cleans it all up
                   (i.e. it frees any demangle allocation once copied from).

   (2) type_name_rt<T>
                   A std::string_view global constant (a view into the
                   demangle buffer, on CXXABI, which is not ever free'd).
                   All work is done in static initialization, before main()

   Failure is signalled by an empty return value; ""
   (indicates a demangle failure as typeid is assumed fail-safe).
   Requirements:
       C++17 for string_view, constexpr-if, CTAD (unique_ptr) and __has_include
       RTTI, the compiler's runtime type information, must be enabled
   Dependencies: <string>,<string_view>,<type_traits> for std::conditional
      <typeinfo> (RTTI)
                 for typeid(T).name(), an implementation-defined name.
      <cxxabi.h> (on CXXABI platforms only - GCC, Clang, etc.)
                 for abi::__cxa_demangle(name,...)
                 to map typeid(T).name to a human readable name for T.
                 <cstdlib> for std::free, <memory> for std::unique_ptr
   E.g.
       int i;
       std::cout << type_name_rt<decltype(i)> << "\n^^^ tada!";
       --- stdout ---
       int
       ^^^ tada!
*/

// IdT<T> wraps T as template param so typeid can't decay ref or cv quals.
// An implementation detail; must be a 3-character id, any 3 chars will do.
template <typename T> struct IdT {};

namespace impl
{
// demangle<bool Free=false>( const char* name)
//
//  (1) On non-CXXABI returns name, regardless of the template parameter.
//      i.e. the function does nothing but return its parameter, a char*.
//
//  (2) On CXXABI the demangle ABI is called and the result is returned
//      with return type depending on the boolean template argument:
//    (a) char* by default (Free=false). Any demangle malloc is not free'd.
//    (b) unique_ptr<char> (Free=true) to RAII-free any malloc'd chars.
//
//     The input name should be a valid mangled name like typeid(T).name()
//     Null return value implies demangle fail (no malloc, free is harmless).
//
template <bool Free = false>
auto
demangle(char const* name) noexcept(!CXXABI)
{
  if constexpr (!CXXABI) {
      return name;         // NOP: assume already demangled if not on CXXABI
  } else {
    auto dmg = abi::__cxa_demangle(name, nullptr, nullptr, nullptr);
    if constexpr (Free)
        return std::unique_ptr<char, decltype(std::free)*>( dmg, std::free);
    else
        return dmg;
  }
}

template <bool Free>
using demangle_t = decltype(demangle<Free>(std::declval<char const*>()));

// prefix_len (constant): prefix length of demangled typeid(IdT<T>)
//   for different compilers (remove 4 chars "int>" from the length)
size_t prefix_len()
{
  static size_t const len = std::strlen(demangle<>(typeid(IdT<int>).name()))
                          - std::strlen("int>");
  return len;
}

// type_name_rt<T>()       Returns string, frees any malloc from ABI demangle
// type_name_rt<T,false>() Returns string_view, does not free demangle malloc
//
template <typename T, bool Free = true>
  // The demangled typeid name is passed in as a (default) argument because
  // then the function body is independent of the template args, T & Free.
  // Compilers may emit one function, for all Ts, inlining typeid & demangle.
auto
type_name_rt(
     demangle_t<Free> dmg = demangle<Free>(typeid(IdT<T>).name())
)
noexcept(!CXXABI) -> std::conditional_t<Free, std::string,
                                              std::string_view>
{
  if (dmg)
  {
    size_t const p = prefix_len();
    return { &*dmg + p, std::strlen(&*dmg) - p - 1 };
  }
  return "";
}
} // namespace impl

// type_name_str<T>() Returns a std::string copy of the demangled typeid name.
//
template <typename T>
std::string
const type_name_str() { return impl::type_name_rt<T>(); }

// type_name_rt<T> Global constant; "The Demangle that Never Dangles"
//
template <typename T>
inline
std::string_view
const type_name_rt = impl::type_name_rt<T, false>();
<commit_msg>revert to just typeid in default arg, demangle in body<commit_after>//    Copyright (c) 2018 Will Wray https://keybase.io/willwray
//
//   Distributed under the Boost Software License, Version 1.0.
//          (http://www.boost.org/LICENSE_1_0.txt)

#pragma once

#include <cstring>
#include <string>
#include <string_view>
#include <typeinfo>
#include <type_traits>

#if __has_include(<cxxabi.h>)
#   include <cxxabi.h>
#   include <cstdlib>
#   include <memory>
#endif

constexpr bool CXXABI
{
#if __has_include(<cxxabi.h>)
    true
#endif
};

/*
  "type_name_rt.hpp": get type names at runtime (hence 'rt')
   ^^^^^^^^^^^^^^^^
   This header defines, in global scope (i.e. not namespace'd):
   (1) A function template type_name_str<T>() for extracting a type's name.
   (2) A variable template type_name_rt<T> initialized to the type's name.
      (also an incomplete class template IdT<T>, an implementation detail.)
   The template type parameter T is mapped to a readable name for the type.
   The work is done at runtime by what is the most standard current method;
   runtime type information (RTTI) and, on CXXABI, a demangle call
   (for compile-time alternatives see type_name_pt or type_name_ct).
   (1) type_name_str<T>()
                   Returns a std::string copy of the demangled typeid name.
                   On each call it does all the work, and cleans it all up
                   (i.e. it frees any demangle allocation once copied from).

   (2) type_name_rt<T>
                   A std::string_view global constant (a view into the
                   demangle buffer, on CXXABI, which is not ever free'd).
                   All work is done in static initialization, before main()

   Failure is signalled by an empty return value; ""
   (indicates a demangle failure as typeid is assumed fail-safe).
   Requirements:
       C++17 for string_view, constexpr-if, CTAD (unique_ptr) and __has_include
       RTTI, the compiler's runtime type information, must be enabled
   Dependencies: <string>,<string_view>,<type_traits> for std::conditional
      <typeinfo> (RTTI)
                 for typeid(T).name(), an implementation-defined name.
      <cxxabi.h> (on CXXABI platforms only - GCC, Clang, etc.)
                 for abi::__cxa_demangle(name,...)
                 to map typeid(T).name to a human readable name for T.
                 <cstdlib> for std::free, <memory> for std::unique_ptr
   E.g.
       int i;
       std::cout << type_name_rt<decltype(i)> << "\n^^^ tada!";
       --- stdout ---
       int
       ^^^ tada!
*/

// IdT<T> wraps T as template param so typeid can't decay ref or cv quals.
// An implementation detail; must be a 3-character id, any 3 chars will do.
template <typename T> struct IdT {};

namespace impl
{
// demangle<bool Free=false>( const char* name)
//
//  (1) On non-CXXABI returns name, regardless of the template parameter.
//      i.e. the function does nothing but return its parameter, a char*.
//
//  (2) On CXXABI the demangle ABI is called and the result is returned
//      with return type depending on the boolean template argument:
//    (a) char* by default (Free=false). Any demangle malloc is not free'd.
//    (b) unique_ptr<char> (Free=true) to RAII-free any malloc'd chars.
//
//     The input name should be a valid mangled name like typeid(T).name()
//     Null return value implies demangle fail (no malloc, free is harmless).
//
template <bool Free = false>
auto
demangle(char const* name) noexcept(!CXXABI)
{
  if constexpr (!CXXABI) {
      return name;         // NOP: assume already demangled if not on CXXABI
  } else {
    auto dmg = abi::__cxa_demangle(name, nullptr, nullptr, nullptr);
    if constexpr (Free)
        return std::unique_ptr<char, decltype(std::free)*>( dmg, std::free);
    else
        return dmg;
  }
}

template <bool Free>
using demangle_t = decltype(demangle<Free>(std::declval<char const*>()));

// prefix_len (constant): prefix length of demangled typeid(IdT<T>)
//   for different compilers (remove 4 chars "int>" from the length)
size_t prefix_len()
{
  static size_t const len = std::strlen(demangle<>(typeid(IdT<int>).name()))
                          - std::strlen("int>");
  return len;
}

// type_name_rt<T>()       Returns string, frees any malloc from ABI demangle
// type_name_rt<T,false>() Returns string_view, does not free demangle malloc
//
template <typename T, bool Free = true>
  // The typeid name is passed in as a (default) argument because
  // then the function body is independent of the template type arg T.
  // Compilers may emit one function, for all Ts, inlining typeid & demangle.
auto
type_name_rt( char const* tid = typeid(IdT<T>).name() ) noexcept(!CXXABI)
 ->
    std::conditional_t<Free, std::string,
                             std::string_view>
{
  if (auto dmg = demangle<Free>(tid))
  {
    size_t const p = prefix_len();
    return { &*dmg + p, std::strlen(&*dmg) - p - 1 };
  }
  return "";
}
} // namespace impl

// type_name_str<T>() Returns a std::string copy of the demangled typeid name.
//
template <typename T>
std::string
const type_name_str() { return impl::type_name_rt<T>(); }

// type_name_rt<T> Global constant; "The Demangle that Never Dangles"
//
template <typename T>
inline
std::string_view
const type_name_rt = impl::type_name_rt<T, false>();
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <fstream>

#include "sre/Texture.hpp"
#include "sre/Renderer.hpp"
#include "sre/Material.hpp"
#include "sre/SDLRenderer.hpp"

#include <glm/gtx/euler_angles.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <sre/ModelImporter.hpp>
#include <glm/gtx/string_cast.hpp>

using namespace sre;

class SpinningCubeExample {
public:
    SpinningCubeExample(){
        r.init();

        SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
        r.otherEvent = [&](SDL_Event& e){
            if (e.type == SDL_DROPFILE){
                auto dropped_filedir = e.drop.file;
                loadObjFile(dropped_filedir);
                SDL_free(dropped_filedir);    // Free dropped_filedir memory
            }
        };

        camera.lookAt({0,0,3},{0,0,0},{0,1,0});
        camera.setPerspectiveProjection(60,0.1,farPlane);

        auto material = Shader::getStandard()->createMaterial();
        material->setColor({1.0f,1.0f,1.0f,1.0f});
        material->setSpecularity(20.0f);
        materials.push_back(material);

        mesh = Mesh::create().withCube().build();
        worldLights.addLight(Light::create().build());
        worldLights.addLight(Light::create().build());
        worldLights.addLight(Light::create().build());
        worldLights.addLight(Light::create().build());

        setLight(1);

        r.frameRender = [&](){
            render();
        };

        r.startEventLoop();
    }

    void setLight(int config){
        if (config == 0){
            worldLights.setAmbientLight({0.05f,0.05f,0.05f});
            worldLights.getLight(0)->lightType = LightType::Point;
            worldLights.getLight(0)->color = {1,1,1};
            worldLights.getLight(0)->position = {0,0,4};
            worldLights.getLight(0)->range = 100;
            worldLights.getLight(1)->lightType = LightType::Unused;
            worldLights.getLight(2)->lightType = LightType::Unused;
            worldLights.getLight(3)->lightType = LightType::Unused;
        }
        if (config == 1){
            worldLights.setAmbientLight({0.05f,0.05f,0.05f});
            worldLights.getLight(0)->lightType = LightType::Directional;
            worldLights.getLight(0)->color = {1,1,1};
            worldLights.getLight(0)->direction = {1,1,.2};
            worldLights.getLight(1)->lightType = LightType::Directional;
            worldLights.getLight(1)->color = {0,0,.3};
            worldLights.getLight(1)->direction = {-1,-1,-.8};
            worldLights.getLight(2)->lightType = LightType::Unused;
            worldLights.getLight(3)->lightType = LightType::Unused;
        }
        if (config == 2){
            worldLights.setAmbientLight({0.05f,0.05f,0.05f});
            worldLights.getLight(0)->lightType = LightType::Directional;
            worldLights.getLight(0)->color = {1,0,0};
            worldLights.getLight(0)->direction = {1,0,0};
            worldLights.getLight(1)->lightType = LightType::Directional;
            worldLights.getLight(1)->color = {0,1,0};
            worldLights.getLight(1)->direction = {-1,0,0};
            worldLights.getLight(2)->lightType = LightType::Unused;
            worldLights.getLight(3)->lightType = LightType::Unused;
        }
        if (config == 3){
            worldLights.setAmbientLight({0.05f,0.05f,0.05f});
            worldLights.getLight(0)->lightType = LightType::Point;
            worldLights.getLight(0)->color = {1,0,0};
            worldLights.getLight(0)->position = {0, 3,0};
            worldLights.getLight(0)->range = 20;
            worldLights.getLight(1)->lightType = LightType::Point;
            worldLights.getLight(1)->color = {0,1,0};
            worldLights.getLight(1)->position = {3, 0,0};
            worldLights.getLight(1)->range = 20;
            worldLights.getLight(2)->lightType = LightType::Point;
            worldLights.getLight(2)->color = {0,-3,0};
            worldLights.getLight(2)->position = {0,-3,0};
            worldLights.getLight(2)->range = 20;
            worldLights.getLight(3)->lightType = LightType::Point;
            worldLights.getLight(3)->color = {1,1,1};
            worldLights.getLight(3)->position = {-3,0,0};
            worldLights.getLight(3)->range = 20;
        }
    }

    void loadObjFile(std::string file){
        auto pos = file.find_last_of(kPathSeparator)+1;
        auto path = file.substr(0,pos);
        auto filename = file.substr(pos);

        materials.clear();
        mesh = ModelImporter::importObj(path, filename, materials);

        std::cout<<materials.size()<< " "<<mesh->getIndexSets()<<std::endl;
        auto bounds = mesh->getBoundsMinMax();
        auto center = glm::mix(bounds[1] , bounds[0],0.5f);
        offset = -center;

        farPlane =  glm::length(bounds[1] - bounds[0]);

        camera.lookAt({0,0,farPlane/2},{0,0,0},{0,1,0});
        camera.setPerspectiveProjection(60,0.1,farPlane);
    }

    void render(){
        auto renderPass = RenderPass::create()
                .withCamera(camera)
                .withWorldLights(&worldLights)
                .withClearColor(true, {0, 0, 0, 1})
                .build();

        renderPass.draw(mesh, glm::scale(glm::vec3(0.5f))*glm::eulerAngleY(glm::radians((float)i))*glm::translate(offset), materials);

        lightGUI();

        // align text
        drawTopText(
#ifdef EMSCRIPTEN
        "Drop obj not supported in Emscripten"
#else
        "Drop obj file here"
#endif
        );

        i++;
    }

    void updateLight(Light* light,int i){
        ImGui::PushID(i);
        ImGui::LabelText("","Light index %i",i);
        const char* items[] = {"Point","Directional","None"};
        ImGui::Combo("Light type", (int*)(&light->lightType), items,3);
        if (light->lightType == LightType::Directional){
            ImGui::DragFloat3("Direction",&light->direction.x);
        }
        else if(light->lightType == LightType::Point){
            ImGui::DragFloat3("Position", &light->position.x);
            ImGui::DragFloat("Range", &light->range);
        }
        if (light->lightType != LightType::Unused){
            ImGui::ColorEdit3("Color", &light->color.x);
        }
        ImGui::PopID();
    }

    void lightGUI(){
        static bool lightOpen = false;
        ImGui::Begin("Lights", &lightOpen);
        if (ImGui::CollapsingHeader("Predefined configs")){
            if (ImGui::Button("Camera light")){
                setLight(0);
            }
            if (ImGui::Button("Twin lights")){
                setLight(1);
            }
            if (ImGui::Button("Twin lights Left-Right")){
                setLight(2);
            }
            if (ImGui::Button("Colorful")){
                setLight(3);
            }
        }

        auto ambientLight = worldLights.getAmbientLight();
        if (ImGui::ColorEdit3("Ambient light",&ambientLight.x)){
            worldLights.setAmbientLight(ambientLight);
        }
        for (int i=0;i<4;i++){
            Light* light = worldLights.getLight(i);
            updateLight(light,i);
        }
        ImGui::End();
    }

    void drawTopText(std::string txt){
        auto size = Renderer::instance->getWindowSize();
        ImVec2 imSize(size.x, 50.0f);
        ImVec2 imPos(0, 0);
        ImGui::SetNextWindowSize(imSize);                                   // imgui window size should have same width as SDL window size
        ImGui::SetNextWindowPos(imPos);
        ImGui::Begin("",nullptr,ImGuiWindowFlags_NoInputs|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoTitleBar);
                                                                            // create window without title
        auto txtSize = ImGui::CalcTextSize(txt.c_str());                    // center text
        ImGui::SetCursorPosX((imSize.x-txtSize.x)/2);
        ImGui::TextWrapped(txt.c_str());
        ImGui::End();
    }
private:
    SDLRenderer r;
    Camera camera;
    WorldLights worldLights;
    std::shared_ptr<Mesh> mesh;
    std::vector<std::shared_ptr<Material>> materials;
    int i=0;
    glm::vec3 offset{0};
    float farPlane = 100;
	const char kPathSeparator =
#ifdef _WIN32
		'\\';
#else
		'/';
#endif
};

int main() {
    new SpinningCubeExample();
    return 0;
}
<commit_msg>Rename obj-viewer example class<commit_after>#include <iostream>
#include <vector>
#include <fstream>

#include "sre/Texture.hpp"
#include "sre/Renderer.hpp"
#include "sre/Material.hpp"
#include "sre/SDLRenderer.hpp"

#include <glm/gtx/euler_angles.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <sre/ModelImporter.hpp>
#include <glm/gtx/string_cast.hpp>

using namespace sre;

class ObjViewerExample {
public:
    ObjViewerExample(){
        r.init();

        SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
        r.otherEvent = [&](SDL_Event& e){
            if (e.type == SDL_DROPFILE){
                auto dropped_filedir = e.drop.file;
                loadObjFile(dropped_filedir);
                SDL_free(dropped_filedir);    // Free dropped_filedir memory
            }
        };

        camera.lookAt({0,0,3},{0,0,0},{0,1,0});
        camera.setPerspectiveProjection(60,0.1,farPlane);

        auto material = Shader::getStandard()->createMaterial();
        material->setColor({1.0f,1.0f,1.0f,1.0f});
        material->setSpecularity(20.0f);
        materials.push_back(material);

        mesh = Mesh::create().withCube().build();
        worldLights.addLight(Light::create().build());
        worldLights.addLight(Light::create().build());
        worldLights.addLight(Light::create().build());
        worldLights.addLight(Light::create().build());

        setLight(1);

        r.frameRender = [&](){
            render();
        };

        r.startEventLoop();
    }

    void setLight(int config){
        if (config == 0){
            worldLights.setAmbientLight({0.05f,0.05f,0.05f});
            worldLights.getLight(0)->lightType = LightType::Point;
            worldLights.getLight(0)->color = {1,1,1};
            worldLights.getLight(0)->position = {0,0,4};
            worldLights.getLight(0)->range = 100;
            worldLights.getLight(1)->lightType = LightType::Unused;
            worldLights.getLight(2)->lightType = LightType::Unused;
            worldLights.getLight(3)->lightType = LightType::Unused;
        }
        if (config == 1){
            worldLights.setAmbientLight({0.05f,0.05f,0.05f});
            worldLights.getLight(0)->lightType = LightType::Directional;
            worldLights.getLight(0)->color = {1,1,1};
            worldLights.getLight(0)->direction = {1,1,.2};
            worldLights.getLight(1)->lightType = LightType::Directional;
            worldLights.getLight(1)->color = {0,0,.3};
            worldLights.getLight(1)->direction = {-1,-1,-.8};
            worldLights.getLight(2)->lightType = LightType::Unused;
            worldLights.getLight(3)->lightType = LightType::Unused;
        }
        if (config == 2){
            worldLights.setAmbientLight({0.05f,0.05f,0.05f});
            worldLights.getLight(0)->lightType = LightType::Directional;
            worldLights.getLight(0)->color = {1,0,0};
            worldLights.getLight(0)->direction = {1,0,0};
            worldLights.getLight(1)->lightType = LightType::Directional;
            worldLights.getLight(1)->color = {0,1,0};
            worldLights.getLight(1)->direction = {-1,0,0};
            worldLights.getLight(2)->lightType = LightType::Unused;
            worldLights.getLight(3)->lightType = LightType::Unused;
        }
        if (config == 3){
            worldLights.setAmbientLight({0.05f,0.05f,0.05f});
            worldLights.getLight(0)->lightType = LightType::Point;
            worldLights.getLight(0)->color = {1,0,0};
            worldLights.getLight(0)->position = {0, 3,0};
            worldLights.getLight(0)->range = 20;
            worldLights.getLight(1)->lightType = LightType::Point;
            worldLights.getLight(1)->color = {0,1,0};
            worldLights.getLight(1)->position = {3, 0,0};
            worldLights.getLight(1)->range = 20;
            worldLights.getLight(2)->lightType = LightType::Point;
            worldLights.getLight(2)->color = {0,-3,0};
            worldLights.getLight(2)->position = {0,-3,0};
            worldLights.getLight(2)->range = 20;
            worldLights.getLight(3)->lightType = LightType::Point;
            worldLights.getLight(3)->color = {1,1,1};
            worldLights.getLight(3)->position = {-3,0,0};
            worldLights.getLight(3)->range = 20;
        }
    }

    void loadObjFile(std::string file){
        auto pos = file.find_last_of(kPathSeparator)+1;
        auto path = file.substr(0,pos);
        auto filename = file.substr(pos);

        materials.clear();
        mesh = ModelImporter::importObj(path, filename, materials);

        std::cout<<materials.size()<< " "<<mesh->getIndexSets()<<std::endl;
        auto bounds = mesh->getBoundsMinMax();
        auto center = glm::mix(bounds[1] , bounds[0],0.5f);
        offset = -center;

        farPlane =  glm::length(bounds[1] - bounds[0]);

        camera.lookAt({0,0,farPlane/2},{0,0,0},{0,1,0});
        camera.setPerspectiveProjection(60,0.1,farPlane);
    }

    void render(){
        auto renderPass = RenderPass::create()
                .withCamera(camera)
                .withWorldLights(&worldLights)
                .withClearColor(true, {0, 0, 0, 1})
                .build();

        renderPass.draw(mesh, glm::scale(glm::vec3(0.5f))*glm::eulerAngleY(glm::radians((float)i))*glm::translate(offset), materials);

        lightGUI();

        // align text
        drawTopText(
#ifdef EMSCRIPTEN
        "Drop obj not supported in Emscripten"
#else
        "Drop obj file here"
#endif
        );

        i++;
    }

    void updateLight(Light* light,int i){
        ImGui::PushID(i);
        ImGui::LabelText("","Light index %i",i);
        const char* items[] = {"Point","Directional","None"};
        ImGui::Combo("Light type", (int*)(&light->lightType), items,3);
        if (light->lightType == LightType::Directional){
            ImGui::DragFloat3("Direction",&light->direction.x);
        }
        else if(light->lightType == LightType::Point){
            ImGui::DragFloat3("Position", &light->position.x);
            ImGui::DragFloat("Range", &light->range);
        }
        if (light->lightType != LightType::Unused){
            ImGui::ColorEdit3("Color", &light->color.x);
        }
        ImGui::PopID();
    }

    void lightGUI(){
        static bool lightOpen = false;
        ImGui::Begin("Lights", &lightOpen);
        if (ImGui::CollapsingHeader("Predefined configs")){
            if (ImGui::Button("Camera light")){
                setLight(0);
            }
            if (ImGui::Button("Twin lights")){
                setLight(1);
            }
            if (ImGui::Button("Twin lights Left-Right")){
                setLight(2);
            }
            if (ImGui::Button("Colorful")){
                setLight(3);
            }
        }

        auto ambientLight = worldLights.getAmbientLight();
        if (ImGui::ColorEdit3("Ambient light",&ambientLight.x)){
            worldLights.setAmbientLight(ambientLight);
        }
        for (int i=0;i<4;i++){
            Light* light = worldLights.getLight(i);
            updateLight(light,i);
        }
        ImGui::End();
    }

    void drawTopText(std::string txt){
        auto size = Renderer::instance->getWindowSize();
        ImVec2 imSize(size.x, 50.0f);
        ImVec2 imPos(0, 0);
        ImGui::SetNextWindowSize(imSize);                                   // imgui window size should have same width as SDL window size
        ImGui::SetNextWindowPos(imPos);
        ImGui::Begin("",nullptr,ImGuiWindowFlags_NoInputs|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoTitleBar);
                                                                            // create window without title
        auto txtSize = ImGui::CalcTextSize(txt.c_str());                    // center text
        ImGui::SetCursorPosX((imSize.x-txtSize.x)/2);
        ImGui::TextWrapped(txt.c_str());
        ImGui::End();
    }
private:
    SDLRenderer r;
    Camera camera;
    WorldLights worldLights;
    std::shared_ptr<Mesh> mesh;
    std::vector<std::shared_ptr<Material>> materials;
    int i=0;
    glm::vec3 offset{0};
    float farPlane = 100;
	const char kPathSeparator =
#ifdef _WIN32
		'\\';
#else
		'/';
#endif
};

int main() {
    new ObjViewerExample();
    return 0;
}
<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2015, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/autograd.h>
#include <af/nn.h>

using namespace af;
using namespace af::nn;
using namespace af::autograd;

int main()
{
    const int inputSize  = 2;
    const int outputSize = 1;
    const int numSamples = 4;
    const double lr = 0.005;

    float hInput[] = {1, 1,
                      0, 0,
                      1, 0,
                      0, 1};

    float hOutput[] = {1,
                       0,
                       1,
                       1};

    auto in = af::array(inputSize, numSamples, hInput);
    auto out = af::array(outputSize, numSamples, hOutput);

    nn::Sequential perceptron;

    perceptron.add(nn::Linear(inputSize, outputSize));
    perceptron.add(nn::Sigmoid());

    Variable result;
    for (int i = 0; i < 10; i++) {

        // Forward propagation
        result = perceptron.forward(nn::input(in));

        // Calculate loss
        // TODO: Use loss function
        af::array diff = out - result.array();
        printf("Error at iteration(%d) : %lf\n", i + 1, af::max<float>(af::abs(diff)));

        // Backward propagation
        auto d_result = Variable(diff, false);
        result.backward(d_result);

        // Update parameters
        // TODO: Should use optimizer
        for (auto param : perceptron.parameters()) {
            param.array() += lr * param.grad().array();
            param.array().eval();
        }
    }
    af_print(result.array());
    return 0;
}
<commit_msg>Fixing perceptron example to use smaller batch size<commit_after>/*******************************************************
 * Copyright (c) 2015, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/autograd.h>
#include <af/nn.h>

using namespace af;
using namespace af::nn;
using namespace af::autograd;

int main()
{
    const int inputSize  = 2;
    const int outputSize = 1;
    const double lr = 0.005;
    const int numSamples = 4;

    float hInput[] = {1, 1,
                      0, 0,
                      1, 0,
                      0, 1};

    float hOutput[] = {1,
                       0,
                       1,
                       1};

    auto in = af::array(inputSize, numSamples, hInput);
    auto out = af::array(outputSize, numSamples, hOutput);

    nn::Sequential perceptron;

    perceptron.add(nn::Linear(inputSize, outputSize));
    perceptron.add(nn::Sigmoid());

    Variable result;
    for (int i = 0; i < 100; i++) {
        for (int j = 0; j < numSamples; j++) {

            af::array in_j = in(af::span, j);
            af::array out_j = out(af::span, j);

            // Forward propagation
            result = perceptron.forward(nn::input(in_j));

            // Calculate loss
            // TODO: Use loss function
            af::array diff = out_j - result.array();

            // Backward propagation
            auto d_result = Variable(diff, false);
            result.backward(d_result);

            // Update parameters
            // TODO: Should use optimizer
            for (auto param : perceptron.parameters()) {
                param.array() += lr * param.grad().array();
                param.array().eval();
            }
        }

        if ((i + 1) % 10 == 0) {
            // Forward propagation
            result = perceptron.forward(nn::input(in));

            // Calculate loss
            // TODO: Use loss function
            af::array diff = out - result.array();
            printf("Average Error at iteration(%d) : %lf\n", i + 1, af::mean<float>(af::abs(diff)));
            printf("Predicted\n");
            af_print(result.array());
            printf("Expected\n");
            af_print(out);
            printf("\n\n");
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1996, California Institute of Technology.
// ALL RIGHTS RESERVED.   U.S. Government Sponsorship acknowledged.
//
// Please read the full copyright notice in the file COPYRIGH
// in this directory.
//
// Author: Todd Karakashian, NASA/Jet Propulsion Laboratory
//         Todd.K.Karakashian@jpl.nasa.gov
//
// $RCSfile: escaping.cc,v $ - Miscellaneous routines for DODS HDF server
//
// $Log: escaping.cc,v $
// Revision 1.7  1998/09/10 19:38:03  jehamby
// Update escaping routines to not mangle high-ASCII characters with toascii()
// and to generate a correct escape sequence in octstring() for such characters
// through judicious casting (cast to a unsigned char, then an unsigned int).
//
// Revision 1.6  1998/03/19 23:29:47  jimg
// Removed old code (that was surrounded by #if 0 ... #endif).
//
// Revision 1.5  1998/02/05 20:14:02  jimg
// DODS now compiles with gcc 2.8.x
//
// Revision 1.4  1997/02/14 04:18:10  jimg
// Added allowable and escape parameters to id2dods and dods2id so that the
// builtin regexs can be overridden if needed.
// Switched to the `fast compile' mode for the Regex objects.
//
// Revision 1.3  1997/02/14 02:24:44  jimg
// Removed reliance on the dods-hdf code.
// Introduced a const int MAXSTR with value 256. This matches the length of
// ID_MAX in the parser.h header (which I did not include since it defines
// a lot of software that is irrelevant to this module).
//
// Revision 1.2  1997/02/14 02:18:16  jimg
// Added to DODS core
//
// Revision 1.2  1996/10/07 21:15:17  todd
// Changes escape character to % from _.
//
// Revision 1.1  1996/09/24 22:38:16  todd
// Initial revision
//
//
/////////////////////////////////////////////////////////////////////////////

// These two routines are for escaping/unescaping strings that are identifiers
// in DODS
// id2dods() -- escape (using WWW hex codes) non-allowable characters in a
// DODS identifier
// dods2id() -- given an WWW hexcode escaped identifier, restore it
//
// These two routines are for escaping/unescaping strings storing attribute
// values.  They use traditional octal escapes (\nnn) because they are
// intended to be viewed by a user
// escattr() -- escape (using traditional octal backslash) non-allowable
// characters in the value of a DODS attribute
// unescattr() -- given an octally escaped string, restore it
//
// These are routines used by the above, not intended to be called directly:
//
// hexstring()
// unhexstring()
// octstring()
// unoctstring()
//
// -Todd

#include <ctype.h>
#include <strstream.h>
#include <iomanip.h>
#include <String.h>

const int MAXSTR = 256;

String hexstring(int val) {
    static char buf[MAXSTR];

    ostrstream(buf,MAXSTR) << hex << setw(2) << setfill('0') <<
	val << ends;

    return (String)buf;
}

char unhexstring(String s) {
    int val;
    static char buf[MAXSTR];

    strcpy(buf,(const char *)s);
    istrstream(buf,MAXSTR) >> hex >> val;

    return (char)val;
}

String octstring(unsigned char val) {
    static char buf[MAXSTR];

    ostrstream(buf,MAXSTR) << oct << setw(3) << setfill('0') <<
	(unsigned int)val << ends;

    return (String)buf;
}

char unoctstring(String s) {
    int val;
    static char buf[MAXSTR];

    strcpy(buf,(const char *)s);
    istrstream(buf,MAXSTR) >> oct >> val;

    return (char)val;
}

// replace characters that are not allowed in DODS identifiers
String id2dods(String s, const String allowable = (char *)0) {
    static Regex badregx("[^0-9a-zA-Z_%]", 1);
    static const char ESC = '%';

    if (allowable) {
	Regex badregx2(allowable, 1);

	int index;
	while ((index = s.index(badregx2)) >= 0)
	    s.at(index,1) = (String)ESC + hexstring(s[index]);
    }
    else {
	int index;
	while ((index = s.index(badregx)) >= 0)
	    s.at(index,1) = (String)ESC + hexstring(s[index]);
    }

    if (isdigit(s[0]))
	s.before(0) = '_';

    return s;
}

String dods2id(String s, const String escape = (char *)0) {
    static Regex escregx("%[0-7][0-9a-fA-F]", 1);

    if (escape) {
	Regex escregx2(escape, 1);
	int index;
	while ((index = s.index(escregx2)) >= 0)
	    s.at(index,3) = unhexstring(s.at(index+1,2));
    }
    else {
	int index;
	while ((index = s.index(escregx)) >= 0)
	    s.at(index,3) = unhexstring(s.at(index+1,2));
    }
    return s;
}

// Escape non-printable characters and quotes from an HDF attribute
String escattr(String s) {
    static Regex nonprintable("[^ !-~]");
    const char ESC = '\\';
    const char QUOTE = '\"';
    const String ESCQUOTE = (String)ESC + (String)QUOTE;

    // escape non-printing characters with octal escape
    int index = 0;
    while ( (index = s.index(nonprintable)) >= 0)
	s.at(index,1) = (String)ESC + octstring(s[index]);

    // escape " with backslash
    index = 0;
    while ( (index = s.index(QUOTE,index)) >= 0) {
	s.at(index,1) = ESCQUOTE;
	index += ESCQUOTE.length();
    }

    return s;
}

// Un-escape special characters, quotes and backslashes from an HDF attribute.
// Note: A regex to match one \ must be defined as
//          Regex foo = "\\\\";
//       because both C++ strings and libg++ regex's also employ \ as
//       an escape character!
String unescattr(String s) {
    static Regex escregx("\\\\[01][0-7][0-7]");  // matches 4 characters
    static Regex escquoteregex("[^\\\\]\\\\\"");  // matches 3 characters
    static Regex escescregex("\\\\\\\\");      // matches 2 characters
    const char ESC = '\\';
    const char QUOTE = '\"';
    const String ESCQUOTE = (String)ESC + (String)QUOTE;

    // unescape any octal-escaped ASCII characters
    int index = 0;
    while ( (index = s.index(escregx,index)) >= 0) {
	s.at(index,4) = unoctstring(s.at(index+1,3));
	index++;
    }

    // unescape any escaped quotes
    index = 0;
    while ( (index = s.index(escquoteregex,index)) >= 0) {
	s.at(index+1,2) = QUOTE;
	index++;
    }

    // unescape any escaped backslashes
    index = 0;
    while ( (index = s.index(escescregex,index)) >= 0) {
	s.at(index,2) = ESC;
	index++;
    }

    return s;
}
<commit_msg>Forgot to update hexstring() to generate correct high-ASCII escapes.<commit_after>
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1996, California Institute of Technology.
// ALL RIGHTS RESERVED.   U.S. Government Sponsorship acknowledged.
//
// Please read the full copyright notice in the file COPYRIGH
// in this directory.
//
// Author: Todd Karakashian, NASA/Jet Propulsion Laboratory
//         Todd.K.Karakashian@jpl.nasa.gov
//
// $RCSfile: escaping.cc,v $ - Miscellaneous routines for DODS HDF server
//
// $Log: escaping.cc,v $
// Revision 1.8  1998/09/10 23:37:11  jehamby
// Forgot to update hexstring() to generate correct high-ASCII escapes.
//
// Revision 1.7  1998/09/10 19:38:03  jehamby
// Update escaping routines to not mangle high-ASCII characters with toascii()
// and to generate a correct escape sequence in octstring() for such characters
// through judicious casting (cast to a unsigned char, then an unsigned int).
//
// Revision 1.6  1998/03/19 23:29:47  jimg
// Removed old code (that was surrounded by #if 0 ... #endif).
//
// Revision 1.5  1998/02/05 20:14:02  jimg
// DODS now compiles with gcc 2.8.x
//
// Revision 1.4  1997/02/14 04:18:10  jimg
// Added allowable and escape parameters to id2dods and dods2id so that the
// builtin regexs can be overridden if needed.
// Switched to the `fast compile' mode for the Regex objects.
//
// Revision 1.3  1997/02/14 02:24:44  jimg
// Removed reliance on the dods-hdf code.
// Introduced a const int MAXSTR with value 256. This matches the length of
// ID_MAX in the parser.h header (which I did not include since it defines
// a lot of software that is irrelevant to this module).
//
// Revision 1.2  1997/02/14 02:18:16  jimg
// Added to DODS core
//
// Revision 1.2  1996/10/07 21:15:17  todd
// Changes escape character to % from _.
//
// Revision 1.1  1996/09/24 22:38:16  todd
// Initial revision
//
//
/////////////////////////////////////////////////////////////////////////////

// These two routines are for escaping/unescaping strings that are identifiers
// in DODS
// id2dods() -- escape (using WWW hex codes) non-allowable characters in a
// DODS identifier
// dods2id() -- given an WWW hexcode escaped identifier, restore it
//
// These two routines are for escaping/unescaping strings storing attribute
// values.  They use traditional octal escapes (\nnn) because they are
// intended to be viewed by a user
// escattr() -- escape (using traditional octal backslash) non-allowable
// characters in the value of a DODS attribute
// unescattr() -- given an octally escaped string, restore it
//
// These are routines used by the above, not intended to be called directly:
//
// hexstring()
// unhexstring()
// octstring()
// unoctstring()
//
// -Todd

#include <ctype.h>
#include <strstream.h>
#include <iomanip.h>
#include <String.h>

const int MAXSTR = 256;

String hexstring(unsigned char val) {
    static char buf[MAXSTR];

    ostrstream(buf,MAXSTR) << hex << setw(2) << setfill('0') <<
	(unsigned int)val << ends;

    return (String)buf;
}

char unhexstring(String s) {
    int val;
    static char buf[MAXSTR];

    strcpy(buf,(const char *)s);
    istrstream(buf,MAXSTR) >> hex >> val;

    return (char)val;
}

String octstring(unsigned char val) {
    static char buf[MAXSTR];

    ostrstream(buf,MAXSTR) << oct << setw(3) << setfill('0') <<
	(unsigned int)val << ends;

    return (String)buf;
}

char unoctstring(String s) {
    int val;
    static char buf[MAXSTR];

    strcpy(buf,(const char *)s);
    istrstream(buf,MAXSTR) >> oct >> val;

    return (char)val;
}

// replace characters that are not allowed in DODS identifiers
String id2dods(String s, const String allowable = (char *)0) {
    static Regex badregx("[^0-9a-zA-Z_%]", 1);
    static const char ESC = '%';

    if (allowable) {
	Regex badregx2(allowable, 1);

	int index;
	while ((index = s.index(badregx2)) >= 0)
	    s.at(index,1) = (String)ESC + hexstring(s[index]);
    }
    else {
	int index;
	while ((index = s.index(badregx)) >= 0)
	    s.at(index,1) = (String)ESC + hexstring(s[index]);
    }

    if (isdigit(s[0]))
	s.before(0) = '_';

    return s;
}

String dods2id(String s, const String escape = (char *)0) {
    static Regex escregx("%[0-7][0-9a-fA-F]", 1);

    if (escape) {
	Regex escregx2(escape, 1);
	int index;
	while ((index = s.index(escregx2)) >= 0)
	    s.at(index,3) = unhexstring(s.at(index+1,2));
    }
    else {
	int index;
	while ((index = s.index(escregx)) >= 0)
	    s.at(index,3) = unhexstring(s.at(index+1,2));
    }
    return s;
}

// Escape non-printable characters and quotes from an HDF attribute
String escattr(String s) {
    static Regex nonprintable("[^ !-~]");
    const char ESC = '\\';
    const char QUOTE = '\"';
    const String ESCQUOTE = (String)ESC + (String)QUOTE;

    // escape non-printing characters with octal escape
    int index = 0;
    while ( (index = s.index(nonprintable)) >= 0)
	s.at(index,1) = (String)ESC + octstring(s[index]);

    // escape " with backslash
    index = 0;
    while ( (index = s.index(QUOTE,index)) >= 0) {
	s.at(index,1) = ESCQUOTE;
	index += ESCQUOTE.length();
    }

    return s;
}

// Un-escape special characters, quotes and backslashes from an HDF attribute.
// Note: A regex to match one \ must be defined as
//          Regex foo = "\\\\";
//       because both C++ strings and libg++ regex's also employ \ as
//       an escape character!
String unescattr(String s) {
    static Regex escregx("\\\\[01][0-7][0-7]");  // matches 4 characters
    static Regex escquoteregex("[^\\\\]\\\\\"");  // matches 3 characters
    static Regex escescregex("\\\\\\\\");      // matches 2 characters
    const char ESC = '\\';
    const char QUOTE = '\"';
    const String ESCQUOTE = (String)ESC + (String)QUOTE;

    // unescape any octal-escaped ASCII characters
    int index = 0;
    while ( (index = s.index(escregx,index)) >= 0) {
	s.at(index,4) = unoctstring(s.at(index+1,3));
	index++;
    }

    // unescape any escaped quotes
    index = 0;
    while ( (index = s.index(escquoteregex,index)) >= 0) {
	s.at(index+1,2) = QUOTE;
	index++;
    }

    // unescape any escaped backslashes
    index = 0;
    while ( (index = s.index(escescregex,index)) >= 0) {
	s.at(index,2) = ESC;
	index++;
    }

    return s;
}
<|endoftext|>


<commit_before>#ifndef ARABICA_XPATH_FUNCTION_HOLDER_HPP
#define ARABICA_XPATH_FUNCTION_HOLDER_HPP

#include <boost/shared_ptr.hpp>
#include "xpath_expression.hpp"
#include "xpath_function.hpp"

namespace Arabica
{
namespace XPath
{
namespace impl
{

template<class function_type, class string_type, class string_adaptor>
XPathFunction<string_type, string_adaptor>* CreateFn(const std::vector<XPathExpression<string_type, string_adaptor> >& argExprs) { return new function_type(argExprs); }

template<class string_type, class string_adaptor>
class FunctionHolder : public XPathExpression_impl<string_type, string_adaptor>
{
public:
  FunctionHolder(XPathFunction<string_type, string_adaptor>* func,
                 const string_type& namespace_uri,
                 const string_type& name) :
    func_(func),
    namespace_uri_(namespace_uri),
    name_(name)
  {
  } // FunctionHolder

  virtual ~FunctionHolder()
  {
    delete func_;
  } // ~FunctionHolder

  const string_type& namespace_uri() const { return namespace_uri_; }
  const string_type& name() const { return name_; }

  virtual ValueType type() const { return func_->type(); }

  virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
                                              const ExecutionContext<string_type, string_adaptor>& executionContext) const
  {
    return XPathValue<string_type, string_adaptor>(func_->evaluate(context, executionContext));
  } // evaluate

  static FunctionHolder* createFunction(const string_type& namespace_uri,
                                        const string_type& name,
                                        const std::vector<XPathExpression<string_type, string_adaptor> >& argExprs,
                                        const CompilationContext<string_type, string_adaptor>& context)
  {
    if(string_adaptor::empty(namespace_uri))
      for(const NamedFunction* fn = FunctionLookupTable; fn->name != 0; ++fn)
        if(name == string_adaptor::construct_from_utf8(fn->name))
          return new FunctionHolder(fn->creator(argExprs), namespace_uri, name);

    XPathFunction<string_type, string_adaptor>* func =
                      context.functionResolver().resolveFunction(namespace_uri, name, argExprs);
    if(func == 0)
    {
      string_type error;
      if(!string_adaptor::empty(namespace_uri))
      {
        string_adaptor::append(error, string_adaptor::construct_from_utf8("{"));
        string_adaptor::append(error, namespace_uri);
        string_adaptor::append(error, string_adaptor::construct_from_utf8("}"));
      } // if ...
      string_adaptor::append(error, name);
      throw UndefinedFunctionException(string_adaptor().asStdString(error));
    } // if(func == 0)

    return new FunctionHolder(func, namespace_uri, name);
  } // createFunction

private:
  XPathFunction<string_type, string_adaptor>* func_;
  string_type namespace_uri_;
  string_type name_;

  typedef XPathFunction<string_type, string_adaptor>* (*CreateFnPtr)(const std::vector<XPathExpression<string_type, string_adaptor> >& argExprs);

  struct NamedFunction { const char* name; CreateFnPtr creator; };

  static const NamedFunction FunctionLookupTable[];
}; // class FunctionHolder

template<class string_type, class string_adaptor>
const typename FunctionHolder<string_type, string_adaptor>::NamedFunction
FunctionHolder<string_type, string_adaptor>::FunctionLookupTable[] =
      { // node-set functions
        { "position",        CreateFn<PositionFn<string_type, string_adaptor>, string_type, string_adaptor> },
        { "last",            CreateFn<LastFn<string_type, string_adaptor>, string_type, string_adaptor> },
        { "count",           CreateFn<CountFn<string_type, string_adaptor>, string_type, string_adaptor> },
        { "local-name",      CreateFn<LocalNameFn<string_type, string_adaptor>, string_type, string_adaptor> },
        { "namespace-uri",   CreateFn<NamespaceURIFn<string_type, string_adaptor>, string_type, string_adaptor> },
        { "name",            CreateFn<NameFn<string_type, string_adaptor>, string_type, string_adaptor> },
        // string functions
        {"string",           CreateFn<StringFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"concat",           CreateFn<ConcatFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"starts-with",      CreateFn<StartsWithFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"contains",         CreateFn<ContainsFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"substring-before", CreateFn<SubstringBeforeFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"substring-after",  CreateFn<SubstringAfterFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"substring",        CreateFn<SubstringFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"string-length",    CreateFn<StringLengthFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"normalize-space",  CreateFn<NormalizeSpaceFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"translate",        CreateFn<TranslateFn<string_type, string_adaptor>, string_type, string_adaptor> },
        // boolean functions
        {"boolean",          CreateFn<BooleanFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"not",              CreateFn<NotFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"true",             CreateFn<TrueFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"false",            CreateFn<FalseFn<string_type, string_adaptor>, string_type, string_adaptor> },
        // number functions
        {"number",           CreateFn<NumberFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"sum",              CreateFn<SumFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"floor",            CreateFn<FloorFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"ceiling",          CreateFn<CeilingFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"round",            CreateFn<RoundFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {0,                  0}
      };

} // namespace impl
} // namespace XPath
} // namespace Arabica

#endif
<commit_msg>pulled out a seperate function resolver for Standard XPath functions<commit_after>#ifndef ARABICA_XPATH_FUNCTION_HOLDER_HPP
#define ARABICA_XPATH_FUNCTION_HOLDER_HPP

#include <boost/shared_ptr.hpp>
#include "xpath_expression.hpp"
#include "xpath_function.hpp"

namespace Arabica
{
namespace XPath
{
namespace impl
{

template<class function_type, class string_type, class string_adaptor>
XPathFunction<string_type, string_adaptor>* CreateFn(const std::vector<XPathExpression<string_type, string_adaptor> >& argExprs) { return new function_type(argExprs); }

template<class string_type, class string_adaptor>
class StandardXPathFunctionResolver
{
public:
  virtual ~StandardXPathFunctionResolver() { }

  virtual XPathFunction<string_type, string_adaptor>*
      resolveFunction(const string_type& namespace_uri,
		      const string_type& name,
		      const std::vector<XPathExpression<string_type, string_adaptor> >& argExprs) const
  {
    if(!string_adaptor::empty(namespace_uri))
      return 0;
    return standardFunction(name, argExprs);
  } // resolveFuncton

  static XPathFunction<string_type, string_adaptor>*
      standardFunction(const string_type& name,
		       const std::vector<XPathExpression<string_type, string_adaptor> >& argExprs)
  {
    for(const NamedFunction* fn = FunctionLookupTable; fn->name != 0; ++fn)
      if(name == string_adaptor::construct_from_utf8(fn->name))
	return fn->creator(argExprs);

    return 0;
  } // standardFunction

private:

  typedef XPathFunction<string_type, string_adaptor>* (*CreateFnPtr)(const std::vector<XPathExpression<string_type, string_adaptor> >& argExprs);

  struct NamedFunction { const char* name; CreateFnPtr creator; };

  static const NamedFunction FunctionLookupTable[];
}; // class StandardXPathFunctionResolver

template<class string_type, class string_adaptor>
const typename StandardXPathFunctionResolver<string_type, string_adaptor>::NamedFunction
StandardXPathFunctionResolver<string_type, string_adaptor>::FunctionLookupTable[] =
      { // node-set functions
        { "position",        CreateFn<PositionFn<string_type, string_adaptor>, string_type, string_adaptor> },
        { "last",            CreateFn<LastFn<string_type, string_adaptor>, string_type, string_adaptor> },
        { "count",           CreateFn<CountFn<string_type, string_adaptor>, string_type, string_adaptor> },
        { "local-name",      CreateFn<LocalNameFn<string_type, string_adaptor>, string_type, string_adaptor> },
        { "namespace-uri",   CreateFn<NamespaceURIFn<string_type, string_adaptor>, string_type, string_adaptor> },
        { "name",            CreateFn<NameFn<string_type, string_adaptor>, string_type, string_adaptor> },
        // string functions
        {"string",           CreateFn<StringFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"concat",           CreateFn<ConcatFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"starts-with",      CreateFn<StartsWithFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"contains",         CreateFn<ContainsFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"substring-before", CreateFn<SubstringBeforeFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"substring-after",  CreateFn<SubstringAfterFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"substring",        CreateFn<SubstringFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"string-length",    CreateFn<StringLengthFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"normalize-space",  CreateFn<NormalizeSpaceFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"translate",        CreateFn<TranslateFn<string_type, string_adaptor>, string_type, string_adaptor> },
        // boolean functions
        {"boolean",          CreateFn<BooleanFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"not",              CreateFn<NotFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"true",             CreateFn<TrueFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"false",            CreateFn<FalseFn<string_type, string_adaptor>, string_type, string_adaptor> },
        // number functions
        {"number",           CreateFn<NumberFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"sum",              CreateFn<SumFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"floor",            CreateFn<FloorFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"ceiling",          CreateFn<CeilingFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {"round",            CreateFn<RoundFn<string_type, string_adaptor>, string_type, string_adaptor> },
        {0,                  0}
      };

template<class string_type, class string_adaptor>
class FunctionHolder : public XPathExpression_impl<string_type, string_adaptor>
{
public:
  FunctionHolder(XPathFunction<string_type, string_adaptor>* func,
                 const string_type& namespace_uri,
                 const string_type& name) :
    func_(func),
    namespace_uri_(namespace_uri),
    name_(name)
  {
  } // FunctionHolder

  virtual ~FunctionHolder()
  {
    delete func_;
  } // ~FunctionHolder

  const string_type& namespace_uri() const { return namespace_uri_; }
  const string_type& name() const { return name_; }

  virtual ValueType type() const { return func_->type(); }

  virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
                                              const ExecutionContext<string_type, string_adaptor>& executionContext) const
  {
    return XPathValue<string_type, string_adaptor>(func_->evaluate(context, executionContext));
  } // evaluate

  static FunctionHolder* createFunction(const string_type& namespace_uri,
                                        const string_type& name,
                                        const std::vector<XPathExpression<string_type, string_adaptor> >& argExprs,
                                        const CompilationContext<string_type, string_adaptor>& context)
  {
    XPathFunction<string_type, string_adaptor>* func = 0;

    if(string_adaptor::empty(namespace_uri))
      func = StandardXPathFunctionResolver<string_type, string_adaptor>::standardFunction(name, argExprs);
    if(func == 0)
      func = context.functionResolver().resolveFunction(namespace_uri, name, argExprs);

    if(func == 0)
    {
      string_type error;
      if(!string_adaptor::empty(namespace_uri))
      {
        string_adaptor::append(error, string_adaptor::construct_from_utf8("{"));
        string_adaptor::append(error, namespace_uri);
        string_adaptor::append(error, string_adaptor::construct_from_utf8("}"));
      } // if ...
      string_adaptor::append(error, name);
      throw UndefinedFunctionException(string_adaptor().asStdString(error));
    } // if(func == 0)

    return new FunctionHolder(func, namespace_uri, name);
  } // createFunction

private:
  XPathFunction<string_type, string_adaptor>* func_;
  string_type namespace_uri_;
  string_type name_;
}; // class FunctionHolder

} // namespace impl
} // namespace XPath
} // namespace Arabica

#endif
<|endoftext|>