<commit_before>#ifndef __WORLD_HPP_INCLUDED
#define __WORLD_HPP_INCLUDED

#include "code/ylikuutio/common/globals.hpp"

// Include GLFW
#ifndef __GLFW3_H_INCLUDED
#define __GLFW3_H_INCLUDED
#include <glfw3.h>
#endif

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <iostream> // std::cout, std::cin, std::cerr
#include <queue>    // std::queue
#include <stdint.h> // uint32_t etc.
#include <vector>   // std::vector

// `Universe`, `Scene`, `Shader`, `Material`, `Species`, `Object`.
// `Universe`, `Scene`, `Shader`, `Material`, `VectorFont`, `Glyph`, `Object`.
// `Universe` must be created before any `Scene`. `parent_pointer` must be given to each `Scene`.
// `Scene` must be created before any `Shader`. `parent_pointer` must be given to each `Shader`.
// `Shader` must be created before any `Material`. `parent_pointer` must be given to each `Material`.
// `Material` must be created before any `Species`. `parent_pointer` must be given to each `Species`.
// `Species` must be create before any `Object` of that `Species`. `parent_pointer` must be given to each `Object` of the `Species`.
//
//
// Hierarchy of regular objects (including terrain species):
//
//    Universe
//       ^
//     Scene
//       ^
//     Shader
//       ^
//    Material
//       ^
//    Species
//       ^
//     Object
//
// Please note that for regular objects the hierarchy above is both the ontological hierarchy and the rendering hierarchy.
//
// Ontological hierarchy of glyph (character) objects:
//
//    Universe
//       ^
//     Scene
//       ^
//     Shader
//       ^
//    Material
//       ^
//   VectorFont < Glyph
//       ^
//     Text3D
//       ^
//     Object
//
// Ontological hierarchy affects how objects can be created and how they can be destroyed,
// though the precise ways how objects can be created depends on the functions available.
//
// Rendering hierarchy of glyph (character) objects:
//
//    Universe
//       ^
//     Scene
//       ^
//     Shader
//       ^
//    Material
//       ^
//   VectorFont
//       ^
//     Glyph
//       ^
//     Object
//
// Please note that rendering hierarchy does not include `Text3D` at all, as each `Glyph` points directly to `VectorFont`.
// So, `render_species_or_glyph` is called only once for each glyph, and that call renders all the children of that `Glyph`,
// even if the children (which are of type `Object`) may belong to many different `Text3D` objects.
// `Text3D` is anyway needed in the ontological hierarchy, so that complete 3D texts can be destroyed and manipulated at once.
//
// Deleting a `Universe` also deletes all scenes, all shaders, materials, species, fonts, glyphs and objects that are bound to the same `Universe`.
// Deleting a `Scene` also deletes all shaders, materials, species, fonts, glyphs and objects that are bound to the same `Universe`.
// Deleting a `Shader` also deletes all materials, species, fonts, glyphs and objects that are bound to the same `Shader`.
// Deleting a `Material` also deletes all species, fonts, glyphs and objects that are bound to the same `Material`.
// Deleting a `Species` also deletes all objects that are bound to the same `Species`.
// Deleting an `Object` only deletes the object.

// Characteristics of object type graphs:
// 1. Each object must be an undirected graph.
// 2. Each edge must be a link in the graph.
// 3. The faces of each object must form a closed surface. The only exception is the terrain object, which may have borders.
//
// Modifying object type graphs:
// 1. Translation of a vertex does not require changes in any other nodes of the graph.
// 2. Adding a vertex always requires changes in some other nodes of the graph (unless the graph is empty before adding the vertex).
// 3. Deleting a vertex always requires deletion of edges from some other nodes of the graph (unless the vertex is the only vertex of the graph).
// 4. Deleting a vertex or vertices usually also requires appropriate vertex additions. These changes are called 'complex modifications'.
//
// Adding a vertex or several vertices:
// 1. The new edges must be connected to the existing graph with appropriate links.
// 2. Each new face must be a triangle.
//
// Deleting a vertex or several vertices:
// 1. When a vertex or several vertices are deleted, their links must be deleted too (`Node` destructor handles this).
// 2. If the vertex to be deleted is on the border of a [terrain] object, it can be deleted.
// 3. If the vertices that are neighbors to the vertex to be deleted form only triangeles, the vertex can be deleted without vertex additions.
// 4. Otherwise the vertex cannot be deleted without appropriate vertex and edge additions.
//
// Complex modifications:
// 1. In complex modifications one or more vertices and edges are deleted and one or more vertices and edges are added.
// 2. Complex modifications may also change the topology of the object (tunnels, arcs, etc.).
// 3. If a complex modification causes splitting the object in two or more pieces, each piece becomes a separate object.
// 4. If the splitted object is a terrain object, then the lowest vertex (any vertex with smallest y-coordinate) of each piece is searched and the
//    y-coordinates of these are compared. The piece with the smallest y-coordinate (lowest altitude) remains terrain, other pieces become
//    regular objects. The pieces that become regular objects will be subject to gravity the same way as any regular object.

namespace ontology
{
    class Scene;
    class Shader;

    class Universe
    {
        public:
            // constructor.
            Universe(float world_radius);

            // destructor.
            ~Universe();

            // this method renders the entire world, one scene at a time.
            void render();

            friend class Scene;
            friend class Shader;
            friend class Species;

        private:
            // this method sets a scene pointer.
            void set_scene_pointer(uint32_t childID, ontology::Scene* child_pointer);

            // this method sets a world species pointer.
            void set_terrain_species_pointer(ontology::Species* terrain_species_pointer);

            void compute_matrices_from_inputs();

            void* terrain_species_pointer;              // pointer to world species (used in collision detection).

            float world_radius;

            std::vector<ontology::Scene*> scene_pointer_vector;
            std::queue<uint32_t> free_sceneID_queue;
    };
}

#endif
<commit_msg>`class Universe` contains information about the background color.<commit_after>#ifndef __WORLD_HPP_INCLUDED
#define __WORLD_HPP_INCLUDED

#include "code/ylikuutio/common/globals.hpp"

// Include GLFW
#ifndef __GLFW3_H_INCLUDED
#define __GLFW3_H_INCLUDED
#include <glfw3.h>
#endif

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <iostream> // std::cout, std::cin, std::cerr
#include <queue>    // std::queue
#include <stdint.h> // uint32_t etc.
#include <vector>   // std::vector

// `Universe`, `Scene`, `Shader`, `Material`, `Species`, `Object`.
// `Universe`, `Scene`, `Shader`, `Material`, `VectorFont`, `Glyph`, `Object`.
// `Universe` must be created before any `Scene`. `parent_pointer` must be given to each `Scene`.
// `Scene` must be created before any `Shader`. `parent_pointer` must be given to each `Shader`.
// `Shader` must be created before any `Material`. `parent_pointer` must be given to each `Material`.
// `Material` must be created before any `Species`. `parent_pointer` must be given to each `Species`.
// `Species` must be create before any `Object` of that `Species`. `parent_pointer` must be given to each `Object` of the `Species`.
//
//
// Hierarchy of regular objects (including terrain species):
//
//    Universe
//       ^
//     Scene
//       ^
//     Shader
//       ^
//    Material
//       ^
//    Species
//       ^
//     Object
//
// Please note that for regular objects the hierarchy above is both the ontological hierarchy and the rendering hierarchy.
//
// Ontological hierarchy of glyph (character) objects:
//
//    Universe
//       ^
//     Scene
//       ^
//     Shader
//       ^
//    Material
//       ^
//   VectorFont < Glyph
//       ^
//     Text3D
//       ^
//     Object
//
// Ontological hierarchy affects how objects can be created and how they can be destroyed,
// though the precise ways how objects can be created depends on the functions available.
//
// Rendering hierarchy of glyph (character) objects:
//
//    Universe
//       ^
//     Scene
//       ^
//     Shader
//       ^
//    Material
//       ^
//   VectorFont
//       ^
//     Glyph
//       ^
//     Object
//
// Please note that rendering hierarchy does not include `Text3D` at all, as each `Glyph` points directly to `VectorFont`.
// So, `render_species_or_glyph` is called only once for each glyph, and that call renders all the children of that `Glyph`,
// even if the children (which are of type `Object`) may belong to many different `Text3D` objects.
// `Text3D` is anyway needed in the ontological hierarchy, so that complete 3D texts can be destroyed and manipulated at once.
//
// Deleting a `Universe` also deletes all scenes, all shaders, materials, species, fonts, glyphs and objects that are bound to the same `Universe`.
// Deleting a `Scene` also deletes all shaders, materials, species, fonts, glyphs and objects that are bound to the same `Universe`.
// Deleting a `Shader` also deletes all materials, species, fonts, glyphs and objects that are bound to the same `Shader`.
// Deleting a `Material` also deletes all species, fonts, glyphs and objects that are bound to the same `Material`.
// Deleting a `Species` also deletes all objects that are bound to the same `Species`.
// Deleting an `Object` only deletes the object.

// Characteristics of object type graphs:
// 1. Each object must be an undirected graph.
// 2. Each edge must be a link in the graph.
// 3. The faces of each object must form a closed surface. The only exception is the terrain object, which may have borders.
//
// Modifying object type graphs:
// 1. Translation of a vertex does not require changes in any other nodes of the graph.
// 2. Adding a vertex always requires changes in some other nodes of the graph (unless the graph is empty before adding the vertex).
// 3. Deleting a vertex always requires deletion of edges from some other nodes of the graph (unless the vertex is the only vertex of the graph).
// 4. Deleting a vertex or vertices usually also requires appropriate vertex additions. These changes are called 'complex modifications'.
//
// Adding a vertex or several vertices:
// 1. The new edges must be connected to the existing graph with appropriate links.
// 2. Each new face must be a triangle.
//
// Deleting a vertex or several vertices:
// 1. When a vertex or several vertices are deleted, their links must be deleted too (`Node` destructor handles this).
// 2. If the vertex to be deleted is on the border of a [terrain] object, it can be deleted.
// 3. If the vertices that are neighbors to the vertex to be deleted form only triangeles, the vertex can be deleted without vertex additions.
// 4. Otherwise the vertex cannot be deleted without appropriate vertex and edge additions.
//
// Complex modifications:
// 1. In complex modifications one or more vertices and edges are deleted and one or more vertices and edges are added.
// 2. Complex modifications may also change the topology of the object (tunnels, arcs, etc.).
// 3. If a complex modification causes splitting the object in two or more pieces, each piece becomes a separate object.
// 4. If the splitted object is a terrain object, then the lowest vertex (any vertex with smallest y-coordinate) of each piece is searched and the
//    y-coordinates of these are compared. The piece with the smallest y-coordinate (lowest altitude) remains terrain, other pieces become
//    regular objects. The pieces that become regular objects will be subject to gravity the same way as any regular object.

namespace ontology
{
    class Scene;
    class Shader;

    class Universe
    {
        public:
            // constructor.
            Universe(float world_radius);

            // destructor.
            ~Universe();

            // this method renders the entire world, one scene at a time.
            void render();

            friend class Scene;
            friend class Shader;
            friend class Species;

        private:
            // this method sets a scene pointer.
            void set_scene_pointer(uint32_t childID, ontology::Scene* child_pointer);

            // this method sets a world species pointer.
            void set_terrain_species_pointer(ontology::Species* terrain_species_pointer);

            void compute_matrices_from_inputs();

            void* terrain_species_pointer;              // pointer to world species (used in collision detection).

            float world_radius;

            std::vector<ontology::Scene*> scene_pointer_vector;
            std::queue<uint32_t> free_sceneID_queue;

            GLclampf background_red;
            GLclampf background_green;
            GLclampf background_blue;
            GLclampf background_alpha;
    };
}

#endif
<|endoftext|>


<commit_before>#include "mob.hpp"

player::player(std::string name, std::string area, std::string skill, int level = 1, int EXP = 0)
{
  setName(name);
  setArea(area);
  setSkill(skill);
  setLevel(level);
  setEXP(EXP);
  setMaxHealth();
  setHealth(mobMaxHealth);
  setDamage();
}

//Member function definitions
void mob::setName(std::string name)
{
  mobName = name;
}
void mob::setArea(std::string area)
{
  mobArea = area;
}
void mob::setSkill(std::string skill)
{
  mobSkill = skill;
}
void mob::setLevel(int level)
{
  mobLevel = level;
}
void mob::setEXP(int EXP)
{
  mobEXP = (35 * getLevel());
}
void mob::setHealth(int health)
{
  mobHealth = health;
}
void mob::setMaxHealth()
{
  mobMaxHealth = (63 * getLevel());
}
void mob::setDamage()
{
  mobDamage = (10 * getLevel());
}

//Member function constructors
void mob::getName()
{
  return mobName;
}
void mob::getArea()
{
  return mobArea;
}
void mob::getSkill()
{
  return mobSkill;
}
void mob::getLevel()
{
  return mobLevel;
}
void mob::getHealth()
{
  return mobHealth;
}
void mob::getMaxHealth()
{
  return mobMaxhealth;
}
void mob::getDamage()
{
  return mobDamage;
}
void mob::getEXP()
{
  return mobEXP;
}

<commit_msg>Delete mob.cpp<commit_after><|endoftext|>


<commit_before>#include <algorithm>
#include <fstream>
#include <iterator>
#include <limits>
#include <stdexcept>
#include <string>
#include <typeinfo>

#include <boost/algorithm/string/predicate.hpp>
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>

#include <AlpinoCorpus/Error.hh>
#include <AlpinoCorpus/Entry.hh>
#include <AlpinoCorpus/IterImpl.hh>

#include "DirectoryCorpusReaderPrivate.hh"
#include "util/NameCompare.hh"
#include "util/textfile.hh"

namespace bf = boost::filesystem;

namespace {
    class DirIter : public alpinocorpus::IterImpl
    {
        boost::filesystem::recursive_directory_iterator iter;
        boost::filesystem::path d_directory;

      public:
        DirIter(boost::filesystem::path const &path,
            boost::filesystem::recursive_directory_iterator i);
        alpinocorpus::IterImpl *copy() const;
        bool hasNext();
        alpinocorpus::Entry next(alpinocorpus::CorpusReader const &rdr);
      private:
        bool isValid();
    };

    DirIter::DirIter(
        bf::path const &path, bf::recursive_directory_iterator i) :
        d_directory(path), iter(i)
    {
    }

    alpinocorpus::IterImpl *DirIter::copy() const
    {
        // No pointer members
        return new DirIter(*this);
    }

    bool DirIter::isValid()
    {
        // End is a correct iterator state.
        if (iter == bf::recursive_directory_iterator())
            return true;

        return iter->path().extension() == ".xml";
    }

    bool DirIter::hasNext()
    {
        // Position iterator at the next valid entry
        while (!isValid()) {
          ++iter;
        }

        return iter != bf::recursive_directory_iterator();
    }

    alpinocorpus::Entry DirIter::next(alpinocorpus::CorpusReader const &rdr)
    {
        // We assume the iterator is valid, since hasNext() should be called
        // before next().

        std::string entryPathStr = iter->path().string();
        entryPathStr.erase(0, d_directory.string().size());

        if (entryPathStr[0] == '/')
            entryPathStr.erase(0, 1);

        bf::path entryPath(entryPathStr);

        // Move the iterator.
        ++iter;

        alpinocorpus::Entry entry = {entryPath.string(), ""};

        return entry;
    }

    class SortedDirIter : public alpinocorpus::IterImpl
    {
        std::vector<std::string> d_entries;
        std::vector<std::string>::const_iterator d_iter;

      public:
        SortedDirIter(boost::filesystem::path const &path,
            boost::filesystem::recursive_directory_iterator i);
        alpinocorpus::IterImpl *copy() const;
        bool hasNext();
        alpinocorpus::Entry next(alpinocorpus::CorpusReader const &rdr);
      private:
        SortedDirIter();
        SortedDirIter &operator=(SortedDirIter &other);
        bool isValid();
    };

    SortedDirIter::SortedDirIter(
        bf::path const &path, bf::recursive_directory_iterator i)
    {
        for (; i != bf::recursive_directory_iterator(); i++)
        {
            std::string entryPathStr = i->path().string();
            entryPathStr.erase(0, path.string().size());

            if (entryPathStr[0] == '/')
                entryPathStr.erase(0, 1);

            d_entries.push_back(entryPathStr);
        }

        std::sort(d_entries.begin(), d_entries.end(),
            alpinocorpus::NameCompare());

        d_iter = d_entries.begin();
    }

    SortedDirIter::SortedDirIter() {
    }

    alpinocorpus::IterImpl *SortedDirIter::copy() const
    {
      SortedDirIter *dirIter = new SortedDirIter;
      dirIter->d_entries = d_entries;
      dirIter->d_iter = dirIter->d_entries.begin() +
          std::distance(d_entries.begin(), d_iter);

      return dirIter;
    }

    bool SortedDirIter::isValid()
    {
        // End is a correct iterator state.
        if (d_iter == d_entries.end())
            return true;

        return boost::algorithm::ends_with(*d_iter, ".xml");
    }

    bool SortedDirIter::hasNext()
    {
        // Position iterator at the next valid entry
        while (!isValid()) {
          ++d_iter;
        }

        return d_iter != d_entries.end();
    }

    alpinocorpus::Entry SortedDirIter::next(alpinocorpus::CorpusReader const &rdr)
    {
        // We assume the iterator is valid, since hasNext() should be called

        bf::path entryPath(*d_iter);

        // Move the iterator.
        ++d_iter;

        alpinocorpus::Entry entry = {entryPath.string(), ""};

        return entry;
    }

}

namespace alpinocorpus {

DirectoryCorpusReaderPrivate::DirectoryCorpusReaderPrivate(
    std::string const &directory) :
    d_nEntries(std::numeric_limits<size_t>::max())
{
    if (directory[directory.size() - 1] == '/')
        d_directory = bf::path(directory).parent_path();
    else
        d_directory = bf::path(directory);

    if (!bf::exists(d_directory) ||
        !bf::is_directory(d_directory))
        throw OpenError(directory, "non-existent or not a directory");
}

DirectoryCorpusReaderPrivate::~DirectoryCorpusReaderPrivate()
{}

CorpusReader::EntryIterator DirectoryCorpusReaderPrivate::getEntries(SortOrder sortOrder) const
{
    switch (sortOrder) {
        case NaturalOrder:
            return EntryIterator(new DirIter(d_directory,
                bf::recursive_directory_iterator(d_directory, bf::symlink_option::recurse)));
        case NumericalOrder:
            return EntryIterator(new SortedDirIter(d_directory,
                bf::recursive_directory_iterator(d_directory, bf::symlink_option::recurse)));
        default:
            BOOST_ASSERT_MSG(false, "Unexpected sort order.");
    }
}

std::string DirectoryCorpusReaderPrivate::getName() const
{
  return d_directory.string();
}

size_t DirectoryCorpusReaderPrivate::getSize() const
{
    if (d_nEntries == std::numeric_limits<size_t>::max())
    {
      size_t nEntries = 0;

      EntryIterator i = getEntries(NaturalOrder);
      while (i.hasNext())
      {
        ++nEntries;
        i.next(*this);
      }

      d_nEntries = nEntries;
    }

    return d_nEntries;
}

std::string DirectoryCorpusReaderPrivate::readEntry(std::string const &entry) const
{
    bf::path p(d_directory);
    p /= entry;
    return util::readFile(p.string());
}

bf::path DirectoryCorpusReaderPrivate::cachePath() const
{
    return d_directory.parent_path() / d_directory.filename().replace_extension(".dir_index");
}

}   // namespace alpinocorpus
<commit_msg>Fix compiler warning.<commit_after>#include <algorithm>
#include <fstream>
#include <iterator>
#include <limits>
#include <stdexcept>
#include <string>
#include <typeinfo>

#include <boost/algorithm/string/predicate.hpp>
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>

#include <AlpinoCorpus/Error.hh>
#include <AlpinoCorpus/Entry.hh>
#include <AlpinoCorpus/IterImpl.hh>

#include "DirectoryCorpusReaderPrivate.hh"
#include "util/NameCompare.hh"
#include "util/textfile.hh"

namespace bf = boost::filesystem;

namespace {
    class DirIter : public alpinocorpus::IterImpl
    {
        boost::filesystem::recursive_directory_iterator iter;
        boost::filesystem::path d_directory;

      public:
        DirIter(boost::filesystem::path const &path,
            boost::filesystem::recursive_directory_iterator i);
        alpinocorpus::IterImpl *copy() const;
        bool hasNext();
        alpinocorpus::Entry next(alpinocorpus::CorpusReader const &rdr);
      private:
        bool isValid();
    };

    DirIter::DirIter(
        bf::path const &path, bf::recursive_directory_iterator i) :
        d_directory(path), iter(i)
    {
    }

    alpinocorpus::IterImpl *DirIter::copy() const
    {
        // No pointer members
        return new DirIter(*this);
    }

    bool DirIter::isValid()
    {
        // End is a correct iterator state.
        if (iter == bf::recursive_directory_iterator())
            return true;

        return iter->path().extension() == ".xml";
    }

    bool DirIter::hasNext()
    {
        // Position iterator at the next valid entry
        while (!isValid()) {
          ++iter;
        }

        return iter != bf::recursive_directory_iterator();
    }

    alpinocorpus::Entry DirIter::next(alpinocorpus::CorpusReader const &rdr)
    {
        // We assume the iterator is valid, since hasNext() should be called
        // before next().

        std::string entryPathStr = iter->path().string();
        entryPathStr.erase(0, d_directory.string().size());

        if (entryPathStr[0] == '/')
            entryPathStr.erase(0, 1);

        bf::path entryPath(entryPathStr);

        // Move the iterator.
        ++iter;

        alpinocorpus::Entry entry = {entryPath.string(), ""};

        return entry;
    }

    class SortedDirIter : public alpinocorpus::IterImpl
    {
        std::vector<std::string> d_entries;
        std::vector<std::string>::const_iterator d_iter;

      public:
        SortedDirIter(boost::filesystem::path const &path,
            boost::filesystem::recursive_directory_iterator i);
        alpinocorpus::IterImpl *copy() const;
        bool hasNext();
        alpinocorpus::Entry next(alpinocorpus::CorpusReader const &rdr);
      private:
        SortedDirIter();
        SortedDirIter &operator=(SortedDirIter &other);
        bool isValid();
    };

    SortedDirIter::SortedDirIter(
        bf::path const &path, bf::recursive_directory_iterator i)
    {
        for (; i != bf::recursive_directory_iterator(); i++)
        {
            std::string entryPathStr = i->path().string();
            entryPathStr.erase(0, path.string().size());

            if (entryPathStr[0] == '/')
                entryPathStr.erase(0, 1);

            d_entries.push_back(entryPathStr);
        }

        std::sort(d_entries.begin(), d_entries.end(),
            alpinocorpus::NameCompare());

        d_iter = d_entries.begin();
    }

    SortedDirIter::SortedDirIter() {
    }

    alpinocorpus::IterImpl *SortedDirIter::copy() const
    {
      SortedDirIter *dirIter = new SortedDirIter;
      dirIter->d_entries = d_entries;
      dirIter->d_iter = dirIter->d_entries.begin() +
          std::distance(d_entries.begin(), d_iter);

      return dirIter;
    }

    bool SortedDirIter::isValid()
    {
        // End is a correct iterator state.
        if (d_iter == d_entries.end())
            return true;

        return boost::algorithm::ends_with(*d_iter, ".xml");
    }

    bool SortedDirIter::hasNext()
    {
        // Position iterator at the next valid entry
        while (!isValid()) {
          ++d_iter;
        }

        return d_iter != d_entries.end();
    }

    alpinocorpus::Entry SortedDirIter::next(alpinocorpus::CorpusReader const &rdr)
    {
        // We assume the iterator is valid, since hasNext() should be called

        bf::path entryPath(*d_iter);

        // Move the iterator.
        ++d_iter;

        alpinocorpus::Entry entry = {entryPath.string(), ""};

        return entry;
    }

}

namespace alpinocorpus {

DirectoryCorpusReaderPrivate::DirectoryCorpusReaderPrivate(
    std::string const &directory) :
    d_nEntries(std::numeric_limits<size_t>::max())
{
    if (directory[directory.size() - 1] == '/')
        d_directory = bf::path(directory).parent_path();
    else
        d_directory = bf::path(directory);

    if (!bf::exists(d_directory) ||
        !bf::is_directory(d_directory))
        throw OpenError(directory, "non-existent or not a directory");
}

DirectoryCorpusReaderPrivate::~DirectoryCorpusReaderPrivate()
{}

CorpusReader::EntryIterator DirectoryCorpusReaderPrivate::getEntries(SortOrder sortOrder) const
{
    switch (sortOrder) {
        case NaturalOrder:
            return EntryIterator(new DirIter(d_directory,
                bf::recursive_directory_iterator(d_directory, bf::symlink_option::recurse)));
        case NumericalOrder:
            return EntryIterator(new SortedDirIter(d_directory,
                bf::recursive_directory_iterator(d_directory, bf::symlink_option::recurse)));
        default:
            throw NotImplemented("Unexpected sort order.");
    }
}

std::string DirectoryCorpusReaderPrivate::getName() const
{
  return d_directory.string();
}

size_t DirectoryCorpusReaderPrivate::getSize() const
{
    if (d_nEntries == std::numeric_limits<size_t>::max())
    {
      size_t nEntries = 0;

      EntryIterator i = getEntries(NaturalOrder);
      while (i.hasNext())
      {
        ++nEntries;
        i.next(*this);
      }

      d_nEntries = nEntries;
    }

    return d_nEntries;
}

std::string DirectoryCorpusReaderPrivate::readEntry(std::string const &entry) const
{
    bf::path p(d_directory);
    p /= entry;
    return util::readFile(p.string());
}

bf::path DirectoryCorpusReaderPrivate::cachePath() const
{
    return d_directory.parent_path() / d_directory.filename().replace_extension(".dir_index");
}

}   // namespace alpinocorpus
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    TestTDx.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
// This test covers the 3DConnexion device interface.
//
// The command line arguments are:
// -I        => run in interactive mode; unless this is used, the program will
//              not allow interaction and exit

#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"

#include "vtkRenderWindowInteractor.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkActor.h"

#include "vtkPolyDataMapper.h"
#include "vtkCamera.h"

#include "vtkConeSource.h"
#include "vtkProperty.h"
#include "vtkTDxMotionEventInfo.h"
#include "vtkCommand.h"
#include "vtkTransform.h"

class myCommand : public vtkCommand
{
public:
  myCommand()
    {
      this->Camera=0;
      this->T=vtkTransform::New();
    }
  ~myCommand()
    {
      this->T->Delete();
    }
  void Execute(vtkObject *vtkNotUsed(caller), unsigned long eventId,
               void *callData)
    {
      cout << "myCommand::Execute()" << endl;

      const double angleSensitivity=0.02;
      const double translationSensitivity=0.001;
      int *button;
      vtkTDxMotionEventInfo *i;

      double *p;

      switch(eventId)
        {
        case vtkCommand::TDxMotionEvent:
          i=static_cast<vtkTDxMotionEventInfo *>(callData);

          cout << "x=" << i->X << " y=" << i->Y << " z=" << i->Z
               << " angle=" << i->Angle << " rx=" << i->AxisX << " ry="
               << i->AxisY << " rz="<< i->AxisZ <<endl;

          this->T->Identity();

          p=this->Camera->GetFocalPoint();
          this->T->Translate(p[0],p[1],p[2]);
          this->T->RotateWXYZ(i->Angle*angleSensitivity,
                              i->AxisX,i->AxisY,i->AxisZ);
          this->T->Translate(-p[0],-p[1],-p[2]);
          this->T->Translate(i->X*translationSensitivity,
                             i->Y*translationSensitivity,
                             i->Z*translationSensitivity);

          this->Camera->ApplyTransform(this->T);
          this->RenderWindowInteractor->Render();
          break;
        case vtkCommand::TDxButtonPressEvent:
          button=static_cast<int *>(callData);
          cout << "button " << *button << " pressed"<< endl;
          break;
        case vtkCommand::TDxButtonReleaseEvent:
          button=static_cast<int *>(callData);
          cout << "button " << *button << " released"<< endl;
          break;
        default:
          cout << "unexpected VTK event" << endl;
          break;
        }
    }
  void SetCamera(vtkCamera *c)
    {
      this->Camera=c;
    }

  void SetRenderWindowInteractor(vtkRenderWindowInteractor *i)
    {
      this->RenderWindowInteractor=i;
    }

protected:
  vtkCamera *Camera;
  vtkRenderWindowInteractor *RenderWindowInteractor;
  vtkTransform *T;
};

int TestTDx(int argc, char* argv[])
{
  vtkRenderWindowInteractor *iren=vtkRenderWindowInteractor::New();
  iren->SetUseTDx(true);
  vtkRenderWindow *renWin = vtkRenderWindow::New();
  renWin->SetMultiSamples(0);

  renWin->SetAlphaBitPlanes(1);
  iren->SetRenderWindow(renWin);
  renWin->Delete();

  vtkRenderer *renderer = vtkRenderer::New();
  renWin->AddRenderer(renderer);
  renderer->Delete();

  vtkConeSource *coneSource1=vtkConeSource::New();
  vtkPolyDataMapper *coneMapper1=vtkPolyDataMapper::New();
  coneMapper1->SetInputConnection(coneSource1->GetOutputPort());
  coneSource1->Delete();
  vtkActor *coneActor1=vtkActor::New();
  coneActor1->SetMapper(coneMapper1);
  coneMapper1->Delete();
  coneActor1->SetPosition(-2.0,0.0,0.0);
  renderer->AddActor(coneActor1);
  coneActor1->Delete();

  vtkConeSource *coneSource2=vtkConeSource::New();
  vtkPolyDataMapper *coneMapper2=vtkPolyDataMapper::New();
  coneMapper2->SetInputConnection(coneSource2->GetOutputPort());
  coneSource2->Delete();
  vtkActor *coneActor2=vtkActor::New();
  coneActor2->SetMapper(coneMapper2);
  coneMapper2->Delete();
  coneActor2->SetPosition(0.0,0.0,0.0);
  coneActor2->GetProperty()->SetLighting(false);
  renderer->AddActor(coneActor2);
  coneActor2->Delete();

  vtkConeSource *coneSource3=vtkConeSource::New();
  vtkPolyDataMapper *coneMapper3=vtkPolyDataMapper::New();
  coneMapper3->SetInputConnection(coneSource3->GetOutputPort());
  coneSource3->Delete();
  vtkActor *coneActor3=vtkActor::New();
  coneActor3->SetMapper(coneMapper3);
  coneMapper3->Delete();
  coneActor3->SetPosition(2.0,0.0,0.0);
  renderer->AddActor(coneActor3);
  coneActor3->Delete();

  renderer->SetBackground(0.1,0.3,0.0);
  renWin->SetSize(200,200);

  renWin->Render();

  vtkCamera *camera=renderer->GetActiveCamera();
//  camera->Azimuth(-40.0);
//  camera->Elevation(20.0);
  renderer->ResetCamera();
  renWin->Render();

  myCommand *c=new myCommand;
  c->Register(0);
  c->SetCamera(camera);
  c->SetRenderWindowInteractor(iren);

  iren->AddObserver(vtkCommand::TDxMotionEvent,c,0);
  iren->AddObserver(vtkCommand::TDxButtonPressEvent,c,0);
  iren->AddObserver(vtkCommand::TDxButtonReleaseEvent,c,0);

  int retVal = vtkRegressionTestImage( renWin );
  if ( retVal == vtkRegressionTester::DO_INTERACTOR)
    {
    iren->Start();
    }
  iren->Delete();

  c->Delete();
  c->Delete();

  return !retVal;
}
<commit_msg>ENH:Sensitivity depends on the platform for this test.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestTDx.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
// This test covers the 3DConnexion device interface.
//
// The command line arguments are:
// -I        => run in interactive mode; unless this is used, the program will
//              not allow interaction and exit

#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"

#include "vtkRenderWindowInteractor.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkActor.h"

#include "vtkPolyDataMapper.h"
#include "vtkCamera.h"

#include "vtkConeSource.h"
#include "vtkProperty.h"
#include "vtkTDxMotionEventInfo.h"
#include "vtkCommand.h"
#include "vtkTransform.h"

class myCommand : public vtkCommand
{
public:
  myCommand()
    {
      this->Camera=0;
      this->T=vtkTransform::New();
    }
  ~myCommand()
    {
      this->T->Delete();
    }
  void Execute(vtkObject *vtkNotUsed(caller), unsigned long eventId,
               void *callData)
    {
      cout << "myCommand::Execute()" << endl;
#ifdef _WIN32
      const double angleSensitivity=1.0;
      const double translationSensitivity=1.0;
#else
      const double angleSensitivity=0.02;
      const double translationSensitivity=0.001;
#endif
      int *button;
      vtkTDxMotionEventInfo *i;

      double *p;

      switch(eventId)
        {
        case vtkCommand::TDxMotionEvent:
          i=static_cast<vtkTDxMotionEventInfo *>(callData);

          cout << "x=" << i->X << " y=" << i->Y << " z=" << i->Z
               << " angle=" << i->Angle << " rx=" << i->AxisX << " ry="
               << i->AxisY << " rz="<< i->AxisZ <<endl;

          this->T->Identity();

          p=this->Camera->GetFocalPoint();
          this->T->Translate(p[0],p[1],p[2]);
          this->T->RotateWXYZ(i->Angle*angleSensitivity,
                              i->AxisX,i->AxisY,i->AxisZ);
          this->T->Translate(-p[0],-p[1],-p[2]);
          this->T->Translate(i->X*translationSensitivity,
                             i->Y*translationSensitivity,
                             i->Z*translationSensitivity);

          this->Camera->ApplyTransform(this->T);
          this->RenderWindowInteractor->Render();
          break;
        case vtkCommand::TDxButtonPressEvent:
          button=static_cast<int *>(callData);
          cout << "button " << *button << " pressed"<< endl;
          break;
        case vtkCommand::TDxButtonReleaseEvent:
          button=static_cast<int *>(callData);
          cout << "button " << *button << " released"<< endl;
          break;
        default:
          cout << "unexpected VTK event" << endl;
          break;
        }
    }
  void SetCamera(vtkCamera *c)
    {
      this->Camera=c;
    }

  void SetRenderWindowInteractor(vtkRenderWindowInteractor *i)
    {
      this->RenderWindowInteractor=i;
    }

protected:
  vtkCamera *Camera;
  vtkRenderWindowInteractor *RenderWindowInteractor;
  vtkTransform *T;
};

int TestTDx(int argc, char* argv[])
{
  vtkRenderWindowInteractor *iren=vtkRenderWindowInteractor::New();
  iren->SetUseTDx(true);
  vtkRenderWindow *renWin = vtkRenderWindow::New();
  renWin->SetMultiSamples(0);

  renWin->SetAlphaBitPlanes(1);
  iren->SetRenderWindow(renWin);
  renWin->Delete();

  vtkRenderer *renderer = vtkRenderer::New();
  renWin->AddRenderer(renderer);
  renderer->Delete();

  vtkConeSource *coneSource1=vtkConeSource::New();
  vtkPolyDataMapper *coneMapper1=vtkPolyDataMapper::New();
  coneMapper1->SetInputConnection(coneSource1->GetOutputPort());
  coneSource1->Delete();
  vtkActor *coneActor1=vtkActor::New();
  coneActor1->SetMapper(coneMapper1);
  coneMapper1->Delete();
  coneActor1->SetPosition(-2.0,0.0,0.0);
  renderer->AddActor(coneActor1);
  coneActor1->Delete();

  vtkConeSource *coneSource2=vtkConeSource::New();
  vtkPolyDataMapper *coneMapper2=vtkPolyDataMapper::New();
  coneMapper2->SetInputConnection(coneSource2->GetOutputPort());
  coneSource2->Delete();
  vtkActor *coneActor2=vtkActor::New();
  coneActor2->SetMapper(coneMapper2);
  coneMapper2->Delete();
  coneActor2->SetPosition(0.0,0.0,0.0);
  coneActor2->GetProperty()->SetLighting(false);
  renderer->AddActor(coneActor2);
  coneActor2->Delete();

  vtkConeSource *coneSource3=vtkConeSource::New();
  vtkPolyDataMapper *coneMapper3=vtkPolyDataMapper::New();
  coneMapper3->SetInputConnection(coneSource3->GetOutputPort());
  coneSource3->Delete();
  vtkActor *coneActor3=vtkActor::New();
  coneActor3->SetMapper(coneMapper3);
  coneMapper3->Delete();
  coneActor3->SetPosition(2.0,0.0,0.0);
  renderer->AddActor(coneActor3);
  coneActor3->Delete();

  renderer->SetBackground(0.1,0.3,0.0);
  renWin->SetSize(200,200);

  renWin->Render();

  vtkCamera *camera=renderer->GetActiveCamera();
//  camera->Azimuth(-40.0);
//  camera->Elevation(20.0);
  renderer->ResetCamera();
  renWin->Render();

  myCommand *c=new myCommand;
  c->Register(0);
  c->SetCamera(camera);
  c->SetRenderWindowInteractor(iren);

  iren->AddObserver(vtkCommand::TDxMotionEvent,c,0);
  iren->AddObserver(vtkCommand::TDxButtonPressEvent,c,0);
  iren->AddObserver(vtkCommand::TDxButtonReleaseEvent,c,0);

  int retVal = vtkRegressionTestImage( renWin );
  if ( retVal == vtkRegressionTester::DO_INTERACTOR)
    {
    iren->Start();
    }
  iren->Delete();

  c->Delete();
  c->Delete();

  return !retVal;
}
<|endoftext|>


<commit_before>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2014 Michael Fink
//
/// \file CdsdkDevicePropertyAccess.cpp CDSDK - Device property access
//

// includes
#include "stdafx.h"
#include "CdsdkDevicePropertyAccess.hpp"
#include "CommonPropertyAccess.hpp"

using namespace CDSDK;

/// all device property descriptions for CDSDK
static PropIdDisplayInfo g_aPropIdDisplayInfo[] =
{
   {
      cdDEVICE_PROP_BATTERY_STATUS,
      {
         { BATTERY_LEVEL_NORMAL, _T("Normal") },
         { BATTERY_LEVEL_WEAK, _T("Weak") },
         { BATTERY_LEVEL_SAFETY_LOW, _T("Safety low") },
         { BATTERY_LEVEL_LB, _T("LB") },
         { 0, nullptr }
      }
   },

   {
      cdDEVICE_PROP_SLIDE_SHOW_CAP,
      {
         { 0, _T("N/A") },
         { cdSLIDE_SHOW_CAP_CANON_FORMAT, _T("Canon format slide show file") },
         { cdSLIDE_SHOW_CAP_DPOF, _T("DPOF slide show file") },
         { 0, nullptr }
      }
   },

   {
      cdDEVICE_PROP_PARSE_FACULTIES,
      {
         { 0, _T("N/A") },
         { cdPARSE_SET_PROP_IN_CAMERA, _T("Supports modifying properties") },
         { 0, nullptr }
      }
   },
};

Variant DevicePropertyAccess::Get(cdDevicePropertyID propId) const
{
   // first, get size of property
   cdUInt32 size = GetSize(propId);

   // now get the data bytes
   std::vector<BYTE> vecData(size);

   // may return cdINVALID_PARAMETER, cdINVALID_HANDLE, cdINVALID_POINTER, cdINVALID_ID,
   // cdPROPERTIES_UNAVAILABLE
   cdError err = CDGetDevicePropertyData(m_hSource, propId, &size, &vecData[0], 0);
   LOG_TRACE(_T("CDGetDevicePropertyData(%08x, propId = %08x, &size = %u, buffer, 0) returned %08x\n"),
      m_hSource, propId, size, err);
   CheckError(_T("CDGetDevicePropertyData"), err, __FILE__, __LINE__);

   // convert to variant
   Variant v;
   SetRawCdsdk(v, propId, vecData);
   return v;
}

void DevicePropertyAccess::Set(cdDevicePropertyID propId, Variant v)
{
   // generate data bytes from variant
   std::vector<BYTE> vecData;
   GetRawCdsdk(v, propId, vecData);
   cdUInt32 size = static_cast<cdUInt32>(vecData.size());

   // now set the property

   // may return cdINVALID_PARAMETER, cdINVALID_HANDLE, cdINVALID_POINTER, cdINVALID_ID,
   // cdPROPERTIES_UNAVAILABLE
   cdError err = CDSetDevicePropertyData(m_hSource, propId, &size, &vecData[0]);
   LOG_TRACE(_T("CDSetDevicePropertyData(%08x, propId = %u, &size = %u, buffer) returned %08x\n"),
      m_hSource, propId, size, err);
   CheckError(_T("CDSetDevicePropertyData"), err, __FILE__, __LINE__);
}

cdUInt32 DevicePropertyAccess::GetSize(cdDevicePropertyID propId) const
{
   cdUInt32 size = 0;

   // may return cdINVALID_PARAMETER, cdINVALID_HANDLE, cdINVALID_POINTER, cdINVALID_ID,
   // cdPROPERTIES_UNAVAILABLE
   cdError err = CDGetDevicePropertyData(m_hSource, propId, &size, nullptr, 0);
   LOG_TRACE(_T("CDGetDevicePropertyData(%08x, propId = %08x, &size = %u, nullptr, 0) returned %08x\n"),
      m_hSource, propId, size, err);
   CheckError(_T("CDGetDevicePropertyData"), err, __FILE__, __LINE__);

   return size;
}

/// \note vecData is passed by value, since it is modified in this function anyway
void DevicePropertyAccess::SetRawCdsdk(Variant& v, unsigned int propId, std::vector<unsigned char> vecData)
{
   boost::any variant;
   Variant::VariantType enType = Variant::typeInvalid;
   bool bIsArray = false;

   switch (propId)
   {
      // uint32
   case cdDEVICE_PROP_MODEL_ID:
   case cdDEVICE_PROP_SLIDE_SHOW_CAP: // cdSlideShowCap
   case cdDEVICE_PROP_DPOF_CAP:
   case cdDEVICE_PROP_RELEASE_CONTROL_CAP:
   case cdDEVICE_PROP_RAW_DEVELOP_FACULTIES: // cdRawDevelopFaculty
   case cdDEVICE_PROP_PARSE_FACULTIES: // cdParseFaculty
   case cdDEVICE_PROP_TIME: // cdTime
   case cdDEVICE_PROP_BATTERY_STATUS:
      ATLASSERT(vecData.size() >= 4);
      {
         // little endian
         unsigned int uiValue =
            static_cast<unsigned int>(vecData[0]) |
            (static_cast<unsigned int>(vecData[1]) << 8) |
            (static_cast<unsigned int>(vecData[2]) << 16) |
            (static_cast<unsigned int>(vecData[3]) << 24);
         variant = uiValue;
         enType = Variant::typeUInt32;
      }
      break;

      // bool
   case cdDEVICE_PROP_UPLOAD_FILE_CAP:
   case cdDEVICE_PROP_ROTATION_CAP:
      ATLASSERT(vecData.size() >= 1);
      variant = static_cast<bool>(vecData[0] != 0);
      enType = Variant::typeBool;
      break;

      // uint8
   case cdDEVICE_PROP_DIRECT_TRANSFER_STATUS:
      ATLASSERT(vecData.size() >= 1);
      variant = static_cast<unsigned char>(vecData[0]);
      enType = Variant::typeUInt8;
      break;

      // String
   case cdDEVICE_PROP_MODEL_NAME:
   case cdDEVICE_PROP_OWNER_NAME:
   case cdDEVICE_PROP_FIRMWARE_VERSION:
      vecData.push_back(0);
      variant = CString(reinterpret_cast<const char*>(&vecData[0]));
      enType = Variant::typeString;
      break;

      // custom data, as array of uint8
   case cdDEVICE_PROP_THUMB_VALID_AREA: // this property isn't described in cdType.h, but assume it's an array
   case cdDEVICE_PROP_UNKNOWN1:
      variant = std::vector<unsigned char>(vecData);
      enType = Variant::typeUInt8;
      bIsArray = true;
      break;

   default:
      ATLASSERT(false);
      break;
   }

   v.SetRaw(variant, enType, bIsArray);
}

void DevicePropertyAccess::GetRawCdsdk(const Variant& v, unsigned int propId, std::vector<unsigned char>& vecData)
{
   switch (propId)
   {
      // String
   case cdDEVICE_PROP_MODEL_NAME:
   case cdDEVICE_PROP_OWNER_NAME:
   case cdDEVICE_PROP_FIRMWARE_VERSION:
      ATLASSERT(v.Type() == Variant::typeString);
      {
         CString cszText = v.Get<CString>();
         CStringA cszaText = cszText;
         LPCSTR pszaText = cszaText.GetString();
         vecData.assign(pszaText, pszaText+strlen(pszaText)+1);
      }
      break;

   default:
      ATLASSERT(false);
      break;
   }
}

CString DevicePropertyAccess::NameFromId(unsigned int propId) throw()
{
   cdDevicePropertyID devicePropId = static_cast<cdDevicePropertyID>(propId);

   LPCTSTR pszName = _T("???");
   switch (devicePropId)
   {
   case cdDEVICE_PROP_INVALID:                  pszName = _T("Invalid property ID"); break;
   case cdDEVICE_PROP_MODEL_ID:                 pszName = _T("Camera model ID"); break;
   case cdDEVICE_PROP_MODEL_NAME:               pszName = _T("Camera model name"); break;
   case cdDEVICE_PROP_SLIDE_SHOW_CAP:           pszName = _T("Slide show capacity"); break;
   case cdDEVICE_PROP_UPLOAD_FILE_CAP:          pszName = _T("CDAddPicture support"); break;
   case cdDEVICE_PROP_ROTATION_CAP:             pszName = _T("Image rotation support"); break;
   case cdDEVICE_PROP_DPOF_CAP:                 pszName = _T("Supported DPOF version number"); break;
   case cdDEVICE_PROP_THUMB_VALID_AREA:         pszName = _T("Valid area in the DCF thumbnail data"); break;
   case cdDEVICE_PROP_RELEASE_CONTROL_CAP:      pszName = _T("Remote release control capability"); break;
   case cdDEVICE_PROP_RAW_DEVELOP_FACULTIES:    pszName = _T("RAW file specification data"); break;
   case cdDEVICE_PROP_PARSE_FACULTIES:          pszName = _T("File parser data"); break;
   case cdDEVICE_PROP_OWNER_NAME:               pszName = _T("Owner name"); break;
   case cdDEVICE_PROP_TIME:                     pszName = _T("Device time"); break;
   case cdDEVICE_PROP_FIRMWARE_VERSION:         pszName = _T("Firmware version"); break;
   case cdDEVICE_PROP_BATTERY_STATUS:           pszName = _T("Battery status"); break;
   case cdDEVICE_PROP_DIRECT_TRANSFER_STATUS:   pszName = _T("Direct transfer status"); break;
   case cdDEVICE_PROP_UNKNOWN1:                 pszName = _T("?? unknown ??"); break;
   }

   return pszName;
}

CString DevicePropertyAccess::DisplayTextFromIdAndValue(unsigned int propId, Variant value)
{
   cdDevicePropertyID devicePropId = static_cast<cdDevicePropertyID>(propId);

   CString cszText;

   switch (devicePropId)
   {
   case cdDEVICE_PROP_TIME: // cdTime
      {
         cdTime time = value.Get<unsigned int>();

         FILETIME fileTime = { 0 };
         ATLVERIFY(TRUE == DosDateTimeToFileTime(HIWORD(time), LOWORD(time), &fileTime));

         SYSTEMTIME systemTime = { 0 };
         ATLVERIFY(TRUE == FileTimeToSystemTime(&fileTime, &systemTime));

         CString cszDate;
         GetDateFormat(LOCALE_USER_DEFAULT, 0, &systemTime, _T("yyyy'-'MM'-'dd"), cszDate.GetBuffer(32), 32);
         cszDate.ReleaseBuffer();

         CString cszTime;
         GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systemTime, _T(" HH':'mm':'ss"), cszTime.GetBuffer(32), 32);
         cszTime.ReleaseBuffer();

         cszText = cszDate + cszTime;
      }
      break;

   default:
      if (!FormatValueById(g_aPropIdDisplayInfo, sizeof(g_aPropIdDisplayInfo) / sizeof(*g_aPropIdDisplayInfo),
         propId, value, cszText))
         cszText = value.ToString();
      break;
   }

   return cszText;
}
<commit_msg>improved device property logging<commit_after>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2014 Michael Fink
//
/// \file CdsdkDevicePropertyAccess.cpp CDSDK - Device property access
//

// includes
#include "stdafx.h"
#include "CdsdkDevicePropertyAccess.hpp"
#include "CommonPropertyAccess.hpp"

using namespace CDSDK;

/// all device property descriptions for CDSDK
static PropIdDisplayInfo g_aPropIdDisplayInfo[] =
{
   {
      cdDEVICE_PROP_BATTERY_STATUS,
      {
         { BATTERY_LEVEL_NORMAL, _T("Normal") },
         { BATTERY_LEVEL_WEAK, _T("Weak") },
         { BATTERY_LEVEL_SAFETY_LOW, _T("Safety low") },
         { BATTERY_LEVEL_LB, _T("LB") },
         { 0, nullptr }
      }
   },

   {
      cdDEVICE_PROP_SLIDE_SHOW_CAP,
      {
         { 0, _T("N/A") },
         { cdSLIDE_SHOW_CAP_CANON_FORMAT, _T("Canon format slide show file") },
         { cdSLIDE_SHOW_CAP_DPOF, _T("DPOF slide show file") },
         { 0, nullptr }
      }
   },

   {
      cdDEVICE_PROP_PARSE_FACULTIES,
      {
         { 0, _T("N/A") },
         { cdPARSE_SET_PROP_IN_CAMERA, _T("Supports modifying properties") },
         { 0, nullptr }
      }
   },
};

Variant DevicePropertyAccess::Get(cdDevicePropertyID propId) const
{
   // first, get size of property
   cdUInt32 size = GetSize(propId);

   // now get the data bytes
   std::vector<BYTE> vecData(size);

   // may return cdINVALID_PARAMETER, cdINVALID_HANDLE, cdINVALID_POINTER, cdINVALID_ID,
   // cdPROPERTIES_UNAVAILABLE
   cdError err = CDGetDevicePropertyData(m_hSource, propId, &size, &vecData[0], 0);
   if (err != cdOK) LOG_TRACE(_T("CDGetDevicePropertyData(%08x, propId = %08x \"%s\", &size = %u, buffer, 0) returned %08x\n"),
      m_hSource, propId, NameFromId(propId).GetString(), size, err);
   CheckError(_T("CDGetDevicePropertyData"), err, __FILE__, __LINE__);

   // convert to variant
   Variant v;
   SetRawCdsdk(v, propId, vecData);
   return v;
}

void DevicePropertyAccess::Set(cdDevicePropertyID propId, Variant v)
{
   // generate data bytes from variant
   std::vector<BYTE> vecData;
   GetRawCdsdk(v, propId, vecData);
   cdUInt32 size = static_cast<cdUInt32>(vecData.size());

   // now set the property

   // may return cdINVALID_PARAMETER, cdINVALID_HANDLE, cdINVALID_POINTER, cdINVALID_ID,
   // cdPROPERTIES_UNAVAILABLE
   cdError err = CDSetDevicePropertyData(m_hSource, propId, &size, &vecData[0]);
   LOG_TRACE(_T("CDSetDevicePropertyData(%08x, propId = %u, &size = %u, buffer) returned %08x\n"),
      m_hSource, propId, size, err);
   CheckError(_T("CDSetDevicePropertyData"), err, __FILE__, __LINE__);
}

cdUInt32 DevicePropertyAccess::GetSize(cdDevicePropertyID propId) const
{
   cdUInt32 size = 0;

   // may return cdINVALID_PARAMETER, cdINVALID_HANDLE, cdINVALID_POINTER, cdINVALID_ID,
   // cdPROPERTIES_UNAVAILABLE
   cdError err = CDGetDevicePropertyData(m_hSource, propId, &size, nullptr, 0);
   if (err != cdOK) LOG_TRACE(_T("CDGetDevicePropertyData(%08x, propId = %08x \"%s\", &size = %u, nullptr, 0) returned %08x\n"),
      m_hSource, propId, NameFromId(propId).GetString(), size, err);
   CheckError(_T("CDGetDevicePropertyData"), err, __FILE__, __LINE__);

   return size;
}

/// \note vecData is passed by value, since it is modified in this function anyway
void DevicePropertyAccess::SetRawCdsdk(Variant& v, unsigned int propId, std::vector<unsigned char> vecData)
{
   boost::any variant;
   Variant::VariantType enType = Variant::typeInvalid;
   bool bIsArray = false;

   switch (propId)
   {
      // uint32
   case cdDEVICE_PROP_MODEL_ID:
   case cdDEVICE_PROP_SLIDE_SHOW_CAP: // cdSlideShowCap
   case cdDEVICE_PROP_DPOF_CAP:
   case cdDEVICE_PROP_RELEASE_CONTROL_CAP:
   case cdDEVICE_PROP_RAW_DEVELOP_FACULTIES: // cdRawDevelopFaculty
   case cdDEVICE_PROP_PARSE_FACULTIES: // cdParseFaculty
   case cdDEVICE_PROP_TIME: // cdTime
   case cdDEVICE_PROP_BATTERY_STATUS:
      ATLASSERT(vecData.size() >= 4);
      {
         // little endian
         unsigned int uiValue =
            static_cast<unsigned int>(vecData[0]) |
            (static_cast<unsigned int>(vecData[1]) << 8) |
            (static_cast<unsigned int>(vecData[2]) << 16) |
            (static_cast<unsigned int>(vecData[3]) << 24);
         variant = uiValue;
         enType = Variant::typeUInt32;
      }
      break;

      // bool
   case cdDEVICE_PROP_UPLOAD_FILE_CAP:
   case cdDEVICE_PROP_ROTATION_CAP:
      ATLASSERT(vecData.size() >= 1);
      variant = static_cast<bool>(vecData[0] != 0);
      enType = Variant::typeBool;
      break;

      // uint8
   case cdDEVICE_PROP_DIRECT_TRANSFER_STATUS:
      ATLASSERT(vecData.size() >= 1);
      variant = static_cast<unsigned char>(vecData[0]);
      enType = Variant::typeUInt8;
      break;

      // String
   case cdDEVICE_PROP_MODEL_NAME:
   case cdDEVICE_PROP_OWNER_NAME:
   case cdDEVICE_PROP_FIRMWARE_VERSION:
      vecData.push_back(0);
      variant = CString(reinterpret_cast<const char*>(&vecData[0]));
      enType = Variant::typeString;
      break;

      // custom data, as array of uint8
   case cdDEVICE_PROP_THUMB_VALID_AREA: // this property isn't described in cdType.h, but assume it's an array
   case cdDEVICE_PROP_UNKNOWN1:
      variant = std::vector<unsigned char>(vecData);
      enType = Variant::typeUInt8;
      bIsArray = true;
      break;

   default:
      ATLASSERT(false);
      break;
   }

   v.SetRaw(variant, enType, bIsArray);
}

void DevicePropertyAccess::GetRawCdsdk(const Variant& v, unsigned int propId, std::vector<unsigned char>& vecData)
{
   switch (propId)
   {
      // String
   case cdDEVICE_PROP_MODEL_NAME:
   case cdDEVICE_PROP_OWNER_NAME:
   case cdDEVICE_PROP_FIRMWARE_VERSION:
      ATLASSERT(v.Type() == Variant::typeString);
      {
         CString cszText = v.Get<CString>();
         CStringA cszaText = cszText;
         LPCSTR pszaText = cszaText.GetString();
         vecData.assign(pszaText, pszaText+strlen(pszaText)+1);
      }
      break;

   default:
      ATLASSERT(false);
      break;
   }
}

CString DevicePropertyAccess::NameFromId(unsigned int propId) throw()
{
   cdDevicePropertyID devicePropId = static_cast<cdDevicePropertyID>(propId);

   LPCTSTR pszName = _T("???");
   switch (devicePropId)
   {
   case cdDEVICE_PROP_INVALID:                  pszName = _T("Invalid property ID"); break;
   case cdDEVICE_PROP_MODEL_ID:                 pszName = _T("Camera model ID"); break;
   case cdDEVICE_PROP_MODEL_NAME:               pszName = _T("Camera model name"); break;
   case cdDEVICE_PROP_SLIDE_SHOW_CAP:           pszName = _T("Slide show capacity"); break;
   case cdDEVICE_PROP_UPLOAD_FILE_CAP:          pszName = _T("Picture upload support"); break;
   case cdDEVICE_PROP_ROTATION_CAP:             pszName = _T("Image rotation support"); break;
   case cdDEVICE_PROP_DPOF_CAP:                 pszName = _T("Supported DPOF version number"); break;
   case cdDEVICE_PROP_THUMB_VALID_AREA:         pszName = _T("Valid area in the DCF thumbnail data"); break;
   case cdDEVICE_PROP_RELEASE_CONTROL_CAP:      pszName = _T("Remote release control capability"); break;
   case cdDEVICE_PROP_RAW_DEVELOP_FACULTIES:    pszName = _T("RAW file specification data"); break;
   case cdDEVICE_PROP_PARSE_FACULTIES:          pszName = _T("File parser data"); break;
   case cdDEVICE_PROP_OWNER_NAME:               pszName = _T("Owner name"); break;
   case cdDEVICE_PROP_TIME:                     pszName = _T("Device time"); break;
   case cdDEVICE_PROP_FIRMWARE_VERSION:         pszName = _T("Firmware version"); break;
   case cdDEVICE_PROP_BATTERY_STATUS:           pszName = _T("Battery status"); break;
   case cdDEVICE_PROP_DIRECT_TRANSFER_STATUS:   pszName = _T("Direct transfer status"); break;
   case cdDEVICE_PROP_UNKNOWN1:                 pszName = _T("?? unknown ??"); break;
   }

   return pszName;
}

CString DevicePropertyAccess::DisplayTextFromIdAndValue(unsigned int propId, Variant value)
{
   cdDevicePropertyID devicePropId = static_cast<cdDevicePropertyID>(propId);

   CString cszText;

   switch (devicePropId)
   {
   case cdDEVICE_PROP_TIME: // cdTime
      {
         cdTime time = value.Get<unsigned int>();

         FILETIME fileTime = { 0 };
         ATLVERIFY(TRUE == DosDateTimeToFileTime(HIWORD(time), LOWORD(time), &fileTime));

         SYSTEMTIME systemTime = { 0 };
         ATLVERIFY(TRUE == FileTimeToSystemTime(&fileTime, &systemTime));

         CString cszDate;
         GetDateFormat(LOCALE_USER_DEFAULT, 0, &systemTime, _T("yyyy'-'MM'-'dd"), cszDate.GetBuffer(32), 32);
         cszDate.ReleaseBuffer();

         CString cszTime;
         GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systemTime, _T(" HH':'mm':'ss"), cszTime.GetBuffer(32), 32);
         cszTime.ReleaseBuffer();

         cszText = cszDate + cszTime;
      }
      break;

   default:
      if (!FormatValueById(g_aPropIdDisplayInfo, sizeof(g_aPropIdDisplayInfo) / sizeof(*g_aPropIdDisplayInfo),
         propId, value, cszText))
         cszText = value.ToString();
      break;
   }

   return cszText;
}
<|endoftext|>


<commit_before>//===--- ArithmeticEvaluator.cpp ------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Simple arithmetic evaluator using the Evaluator class.
//
//===----------------------------------------------------------------------===//
#include "swift/AST/DiagnosticEngine.h"
#include "swift/AST/Evaluator.h"
#include "swift/AST/SimpleRequest.h"
#include "swift/Basic/SourceManager.h"
#include "gtest/gtest.h"
#include <cmath>
#include <memory>

using namespace swift;
using namespace llvm;

class ArithmeticExpr {
 public:
  enum class Kind {
    Literal,
    Binary,
  } kind;

  // Note: used for internal caching.
  Optional<double> cachedValue;

 protected:
  ArithmeticExpr(Kind kind) : kind(kind) { }
};

class Literal : public ArithmeticExpr {
 public:
  const double value;

  Literal(double value) : ArithmeticExpr(Kind::Literal), value(value) { }
};

class Binary : public ArithmeticExpr {
 public:
  enum class OperatorKind {
    Sum,
    Product,
  } operatorKind;

  ArithmeticExpr *lhs;
  ArithmeticExpr *rhs;

  Binary(OperatorKind operatorKind, ArithmeticExpr *lhs, ArithmeticExpr *rhs)
    : ArithmeticExpr(Kind::Binary), operatorKind(operatorKind),
      lhs(lhs), rhs(rhs) { }
};

void simple_display(llvm::raw_ostream &out, ArithmeticExpr *expr) {
  switch (expr->kind) {
  case ArithmeticExpr::Kind::Literal:
    out << "Literal: " << static_cast<Literal *>(expr)->value;
    break;

  case ArithmeticExpr::Kind::Binary:
    out << "Binary: ";
    switch (static_cast<Binary *>(expr)->operatorKind) {
    case Binary::OperatorKind::Sum:
      out << "sum";
      break;

    case Binary::OperatorKind::Product:
      out << "product";
      break;
    }
    break;
  }
}

/// Helper to short-circuit errors to NaN.
template<typename Request>
static double evalOrNaN(Evaluator &evaluator, const Request &request) {
  return evaluateOrDefault(evaluator, request, NAN);
}

/// Rule to evaluate the value of the expression.
template<typename Derived, CacheKind Caching>
struct EvaluationRule
  : public SimpleRequest<Derived, double(ArithmeticExpr *), Caching>
{
  using SimpleRequest<Derived, double(ArithmeticExpr *), Caching>
      ::SimpleRequest;

  static bool brokeCycle;

  double evaluate(Evaluator &evaluator, ArithmeticExpr *expr) const {
    switch (expr->kind) {
    case ArithmeticExpr::Kind::Literal:
      return static_cast<Literal *>(expr)->value;

    case ArithmeticExpr::Kind::Binary: {
      auto binary = static_cast<Binary *>(expr);

      // Evaluate the left- and right-hand sides.
      auto lhsValue = evalOrNaN(evaluator, Derived{binary->lhs});
      if (lhsValue != lhsValue) {
        brokeCycle = true;
        return lhsValue;
      }
      auto rhsValue = evalOrNaN(evaluator, Derived{binary->rhs});
      if (rhsValue != rhsValue) {
        brokeCycle = true;
        return rhsValue;
      }

      switch (binary->operatorKind) {
      case Binary::OperatorKind::Sum:
        return lhsValue + rhsValue;

      case Binary::OperatorKind::Product:
        return lhsValue * rhsValue;
      }
    }
    }
  }

  SourceLoc getNearestLoc() const { return SourceLoc(); }
};

template<typename Derived, CacheKind Caching>
bool EvaluationRule<Derived, Caching>::brokeCycle = false;

struct InternallyCachedEvaluationRule :
EvaluationRule<InternallyCachedEvaluationRule, CacheKind::Cached>
{
  using EvaluationRule::EvaluationRule;

  bool isCached() const {
    auto expr = std::get<0>(getStorage());
    switch (expr->kind) {
    case ArithmeticExpr::Kind::Literal:
      return false;

    case ArithmeticExpr::Kind::Binary:
      return true;
    }
  }
};

struct UncachedEvaluationRule
    : EvaluationRule<UncachedEvaluationRule, CacheKind::Uncached> {
  using EvaluationRule::EvaluationRule;
};

struct ExternallyCachedEvaluationRule
    : EvaluationRule<ExternallyCachedEvaluationRule,
                     CacheKind::SeparatelyCached> {
  using EvaluationRule::EvaluationRule;

  bool isCached() const {
    auto expr = std::get<0>(getStorage());

    switch (expr->kind) {
    case ArithmeticExpr::Kind::Literal:
      return false;

    case ArithmeticExpr::Kind::Binary:
      return true;
    }
  }

  Optional<double> getCachedResult() const {
    auto expr = std::get<0>(getStorage());

    return expr->cachedValue;
  }

  void cacheResult(double value) const {
    auto expr = std::get<0>(getStorage());

    expr->cachedValue = value;
  }
};

// Define the arithmetic evaluator's zone.
namespace swift {
#define SWIFT_TYPEID_ZONE ArithmeticEvaluator
#define SWIFT_TYPEID_HEADER "ArithmeticEvaluatorTypeIDZone.def"
#include "swift/Basic/DefineTypeIDZone.h"

#define SWIFT_TYPEID_ZONE ArithmeticEvaluator
#define SWIFT_TYPEID_HEADER "ArithmeticEvaluatorTypeIDZone.def"
#include "swift/Basic/ImplementTypeIDZone.h"

}

/// All of the arithmetic request functions.
static AbstractRequestFunction *arithmeticRequestFunctions[] = {
#define SWIFT_REQUEST(Zone, Name, Sig, Caching, LocOptions)                    \
  reinterpret_cast<AbstractRequestFunction *>(&Name::evaluateRequest),
#include "ArithmeticEvaluatorTypeIDZone.def"
#undef SWIFT_REQUEST
};

TEST(ArithmeticEvaluator, Simple) {
  // (3.14159 + 2.71828) * 42
  ArithmeticExpr *pi = new Literal(3.14159);
  ArithmeticExpr *e = new Literal(2.71828);
  ArithmeticExpr *sum = new Binary(Binary::OperatorKind::Sum, pi, e);
  ArithmeticExpr *lifeUniverseEverything = new Literal(42.0);
  ArithmeticExpr *product = new Binary(Binary::OperatorKind::Product, sum,
                                       lifeUniverseEverything);

  SourceManager sourceMgr;
  DiagnosticEngine diags(sourceMgr);
  Evaluator evaluator(diags,
                      /*debugDumpCycles=*/false,
                      /*buildDependencyGraph=*/true);
  evaluator.registerRequestFunctions(Zone::ArithmeticEvaluator,
                                     arithmeticRequestFunctions);

  const double expectedResult = (3.14159 + 2.71828) * 42.0;
  EXPECT_EQ(evalOrNaN(evaluator, InternallyCachedEvaluationRule(product)),
            expectedResult);

  // Cached response.
  EXPECT_EQ(evalOrNaN(evaluator, InternallyCachedEvaluationRule(product)),
            expectedResult);

  // Uncached
  evaluator.clearCache();
  EXPECT_EQ(evalOrNaN(evaluator, UncachedEvaluationRule(product)),
            expectedResult);
  EXPECT_EQ(evalOrNaN(evaluator, UncachedEvaluationRule(product)),
            expectedResult);

  // External cached query.
  evaluator.clearCache();
  EXPECT_EQ(evalOrNaN(evaluator, ExternallyCachedEvaluationRule(product)),
            expectedResult);
  EXPECT_EQ(*sum->cachedValue, 3.14159 + 2.71828);
  EXPECT_EQ(*product->cachedValue, expectedResult);
  EXPECT_EQ(evalOrNaN(evaluator, ExternallyCachedEvaluationRule(product)),
            expectedResult);
  EXPECT_EQ(*sum->cachedValue, 3.14159 + 2.71828);
  EXPECT_EQ(*product->cachedValue, expectedResult);

  // Dependency printing.

  // Cache some values first, so they show up in the result.
  (void)llvm::cantFail(evaluator(InternallyCachedEvaluationRule(product)),
                       "no explicit cycles were requested");

  std::string productDependencies;
  {
    llvm::raw_string_ostream out(productDependencies);
    evaluator.printDependencies(InternallyCachedEvaluationRule(product), out);
  }

  EXPECT_EQ(productDependencies,
    " `--InternallyCachedEvaluationRule(Binary: product) -> 2.461145e+02\n"
    "     `--InternallyCachedEvaluationRule(Binary: sum) -> 5.859870e+00\n"
    "     |   `--InternallyCachedEvaluationRule(Literal: 3.141590e+00)\n"
    "     |   `--InternallyCachedEvaluationRule(Literal: 2.718280e+00)\n"
    "     `--InternallyCachedEvaluationRule(Literal: 4.200000e+01)\n");

  std::string sumDependencies;
  {
    llvm::raw_string_ostream out(sumDependencies);
    evaluator.printDependencies(ExternallyCachedEvaluationRule(product), out);
  }

  EXPECT_EQ(sumDependencies,
    " `--ExternallyCachedEvaluationRule(Binary: product)\n"
    "     `--ExternallyCachedEvaluationRule(Binary: sum)\n"
    "     |   `--ExternallyCachedEvaluationRule(Literal: 3.141590e+00)\n"
    "     |   `--ExternallyCachedEvaluationRule(Literal: 2.718280e+00)\n"
    "     `--ExternallyCachedEvaluationRule(Literal: 4.200000e+01)\n");

  // Graphviz printing.
  std::string allDependencies;
  {
    llvm::raw_string_ostream out(allDependencies);
    evaluator.printDependenciesGraphviz(out);
  }

  EXPECT_EQ(allDependencies,
    "digraph Dependencies {\n"
    "  request_0 -> request_1;\n"
    "  request_0 -> request_4;\n"
    "  request_1 -> request_3;\n"
    "  request_1 -> request_2;\n"
    "  request_5 -> request_6;\n"
    "  request_5 -> request_9;\n"
    "  request_6 -> request_8;\n"
    "  request_6 -> request_7;\n"
    "  request_10 -> request_11;\n"
    "  request_10 -> request_14;\n"
    "  request_11 -> request_13;\n"
    "  request_11 -> request_12;\n"
    "\n"
    "  request_0 [label=\"ExternallyCachedEvaluationRule(Binary: product)\"];\n"
    "  request_1 [label=\"ExternallyCachedEvaluationRule(Binary: sum)\"];\n"
    "  request_2 [label=\"ExternallyCachedEvaluationRule(Literal: 2.718280e+00)\"];\n"
    "  request_3 [label=\"ExternallyCachedEvaluationRule(Literal: 3.141590e+00)\"];\n"
    "  request_4 [label=\"ExternallyCachedEvaluationRule(Literal: 4.200000e+01)\"];\n"
    "  request_5 [label=\"InternallyCachedEvaluationRule(Binary: product) -> 2.461145e+02\"];\n"
    "  request_6 [label=\"InternallyCachedEvaluationRule(Binary: sum) -> 5.859870e+00\"];\n"
    "  request_7 [label=\"InternallyCachedEvaluationRule(Literal: 2.718280e+00)\"];\n"
    "  request_8 [label=\"InternallyCachedEvaluationRule(Literal: 3.141590e+00)\"];\n"
    "  request_9 [label=\"InternallyCachedEvaluationRule(Literal: 4.200000e+01)\"];\n"
    "  request_10 [label=\"UncachedEvaluationRule(Binary: product)\"];\n"
    "  request_11 [label=\"UncachedEvaluationRule(Binary: sum)\"];\n"
    "  request_12 [label=\"UncachedEvaluationRule(Literal: 2.718280e+00)\"];\n"
    "  request_13 [label=\"UncachedEvaluationRule(Literal: 3.141590e+00)\"];\n"
    "  request_14 [label=\"UncachedEvaluationRule(Literal: 4.200000e+01)\"];\n"
    "}\n");

  // Cleanup
  delete pi;
  delete e;
  delete sum;
  delete lifeUniverseEverything;
  delete product;
}

TEST(ArithmeticEvaluator, Cycle) {
  // (3.14159 + 2.71828) * 42
  ArithmeticExpr *pi = new Literal(3.14159);
  ArithmeticExpr *e = new Literal(2.71828);
  Binary *sum = new Binary(Binary::OperatorKind::Sum, pi, e);
  ArithmeticExpr *lifeUniverseEverything = new Literal(42.0);
  ArithmeticExpr *product = new Binary(Binary::OperatorKind::Product, sum,
                                       lifeUniverseEverything);

  // Introduce a cycle.
  sum->rhs = product;

  SourceManager sourceMgr;
  DiagnosticEngine diags(sourceMgr);
  Evaluator evaluator(diags,
                      /*debugDumpCycles=*/false,
                      /*buildDependencyGraph=*/false);
  evaluator.registerRequestFunctions(Zone::ArithmeticEvaluator,
                                     arithmeticRequestFunctions);

  // Evaluate when there is a cycle.
  UncachedEvaluationRule::brokeCycle = false;
  EXPECT_TRUE(std::isnan(evalOrNaN(evaluator,
                                   UncachedEvaluationRule(product))));
  EXPECT_TRUE(UncachedEvaluationRule::brokeCycle);

  // Cycle-breaking result is cached.
  EXPECT_TRUE(std::isnan(evalOrNaN(evaluator,
                                   UncachedEvaluationRule(product))));
  UncachedEvaluationRule::brokeCycle = false;
  EXPECT_FALSE(UncachedEvaluationRule::brokeCycle);

  // Evaluate when there is a cycle.
  evaluator.clearCache();
  InternallyCachedEvaluationRule::brokeCycle = false;
  EXPECT_TRUE(std::isnan(evalOrNaN(evaluator,
                                   InternallyCachedEvaluationRule(product))));
  EXPECT_TRUE(InternallyCachedEvaluationRule::brokeCycle);

  // Cycle-breaking result is cached.
  InternallyCachedEvaluationRule::brokeCycle = false;
  EXPECT_TRUE(std::isnan(evalOrNaN(evaluator,
                                   InternallyCachedEvaluationRule(product))));
  EXPECT_FALSE(InternallyCachedEvaluationRule::brokeCycle);

  // Evaluate when there is a cycle.
  evaluator.clearCache();
  ExternallyCachedEvaluationRule::brokeCycle = false;
  EXPECT_TRUE(std::isnan(evalOrNaN(evaluator,
                                   ExternallyCachedEvaluationRule(product))));
  EXPECT_TRUE(ExternallyCachedEvaluationRule::brokeCycle);

  // Cycle-breaking result is cached.
  ExternallyCachedEvaluationRule::brokeCycle = false;
  EXPECT_TRUE(std::isnan(evalOrNaN(evaluator,
                                   ExternallyCachedEvaluationRule(product))));
  EXPECT_FALSE(ExternallyCachedEvaluationRule::brokeCycle);

  // Dependency printing.
  std::string productDependencies;
  {
    llvm::raw_string_ostream out(productDependencies);
    evaluator.printDependencies(InternallyCachedEvaluationRule(product), out);
  }

  EXPECT_EQ(productDependencies,
    " `--InternallyCachedEvaluationRule(Binary: product) "
      "(dependency not evaluated)\n");

  // Cleanup
  delete pi;
  delete e;
  delete sum;
  delete lifeUniverseEverything;
  delete product;
}
<commit_msg>[Gardening] Use std::isnan<commit_after>//===--- ArithmeticEvaluator.cpp ------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Simple arithmetic evaluator using the Evaluator class.
//
//===----------------------------------------------------------------------===//
#include "swift/AST/DiagnosticEngine.h"
#include "swift/AST/Evaluator.h"
#include "swift/AST/SimpleRequest.h"
#include "swift/Basic/SourceManager.h"
#include "gtest/gtest.h"
#include <cmath>
#include <memory>

using namespace swift;
using namespace llvm;

class ArithmeticExpr {
 public:
  enum class Kind {
    Literal,
    Binary,
  } kind;

  // Note: used for internal caching.
  Optional<double> cachedValue;

 protected:
  ArithmeticExpr(Kind kind) : kind(kind) { }
};

class Literal : public ArithmeticExpr {
 public:
  const double value;

  Literal(double value) : ArithmeticExpr(Kind::Literal), value(value) { }
};

class Binary : public ArithmeticExpr {
 public:
  enum class OperatorKind {
    Sum,
    Product,
  } operatorKind;

  ArithmeticExpr *lhs;
  ArithmeticExpr *rhs;

  Binary(OperatorKind operatorKind, ArithmeticExpr *lhs, ArithmeticExpr *rhs)
    : ArithmeticExpr(Kind::Binary), operatorKind(operatorKind),
      lhs(lhs), rhs(rhs) { }
};

void simple_display(llvm::raw_ostream &out, ArithmeticExpr *expr) {
  switch (expr->kind) {
  case ArithmeticExpr::Kind::Literal:
    out << "Literal: " << static_cast<Literal *>(expr)->value;
    break;

  case ArithmeticExpr::Kind::Binary:
    out << "Binary: ";
    switch (static_cast<Binary *>(expr)->operatorKind) {
    case Binary::OperatorKind::Sum:
      out << "sum";
      break;

    case Binary::OperatorKind::Product:
      out << "product";
      break;
    }
    break;
  }
}

/// Helper to short-circuit errors to NaN.
template<typename Request>
static double evalOrNaN(Evaluator &evaluator, const Request &request) {
  return evaluateOrDefault(evaluator, request, NAN);
}

/// Rule to evaluate the value of the expression.
template<typename Derived, CacheKind Caching>
struct EvaluationRule
  : public SimpleRequest<Derived, double(ArithmeticExpr *), Caching>
{
  using SimpleRequest<Derived, double(ArithmeticExpr *), Caching>
      ::SimpleRequest;

  static bool brokeCycle;

  double evaluate(Evaluator &evaluator, ArithmeticExpr *expr) const {
    switch (expr->kind) {
    case ArithmeticExpr::Kind::Literal:
      return static_cast<Literal *>(expr)->value;

    case ArithmeticExpr::Kind::Binary: {
      auto binary = static_cast<Binary *>(expr);

      // Evaluate the left- and right-hand sides.
      auto lhsValue = evalOrNaN(evaluator, Derived{binary->lhs});
      if (std::isnan(lhsValue)) {
        brokeCycle = true;
        return lhsValue;
      }
      auto rhsValue = evalOrNaN(evaluator, Derived{binary->rhs});
      if (std::isnan(rhsValue)) {
        brokeCycle = true;
        return rhsValue;
      }

      switch (binary->operatorKind) {
      case Binary::OperatorKind::Sum:
        return lhsValue + rhsValue;

      case Binary::OperatorKind::Product:
        return lhsValue * rhsValue;
      }
    }
    }
  }

  SourceLoc getNearestLoc() const { return SourceLoc(); }
};

template<typename Derived, CacheKind Caching>
bool EvaluationRule<Derived, Caching>::brokeCycle = false;

struct InternallyCachedEvaluationRule :
EvaluationRule<InternallyCachedEvaluationRule, CacheKind::Cached>
{
  using EvaluationRule::EvaluationRule;

  bool isCached() const {
    auto expr = std::get<0>(getStorage());
    switch (expr->kind) {
    case ArithmeticExpr::Kind::Literal:
      return false;

    case ArithmeticExpr::Kind::Binary:
      return true;
    }
  }
};

struct UncachedEvaluationRule
    : EvaluationRule<UncachedEvaluationRule, CacheKind::Uncached> {
  using EvaluationRule::EvaluationRule;
};

struct ExternallyCachedEvaluationRule
    : EvaluationRule<ExternallyCachedEvaluationRule,
                     CacheKind::SeparatelyCached> {
  using EvaluationRule::EvaluationRule;

  bool isCached() const {
    auto expr = std::get<0>(getStorage());

    switch (expr->kind) {
    case ArithmeticExpr::Kind::Literal:
      return false;

    case ArithmeticExpr::Kind::Binary:
      return true;
    }
  }

  Optional<double> getCachedResult() const {
    auto expr = std::get<0>(getStorage());

    return expr->cachedValue;
  }

  void cacheResult(double value) const {
    auto expr = std::get<0>(getStorage());

    expr->cachedValue = value;
  }
};

// Define the arithmetic evaluator's zone.
namespace swift {
#define SWIFT_TYPEID_ZONE ArithmeticEvaluator
#define SWIFT_TYPEID_HEADER "ArithmeticEvaluatorTypeIDZone.def"
#include "swift/Basic/DefineTypeIDZone.h"

#define SWIFT_TYPEID_ZONE ArithmeticEvaluator
#define SWIFT_TYPEID_HEADER "ArithmeticEvaluatorTypeIDZone.def"
#include "swift/Basic/ImplementTypeIDZone.h"

}

/// All of the arithmetic request functions.
static AbstractRequestFunction *arithmeticRequestFunctions[] = {
#define SWIFT_REQUEST(Zone, Name, Sig, Caching, LocOptions)                    \
  reinterpret_cast<AbstractRequestFunction *>(&Name::evaluateRequest),
#include "ArithmeticEvaluatorTypeIDZone.def"
#undef SWIFT_REQUEST
};

TEST(ArithmeticEvaluator, Simple) {
  // (3.14159 + 2.71828) * 42
  ArithmeticExpr *pi = new Literal(3.14159);
  ArithmeticExpr *e = new Literal(2.71828);
  ArithmeticExpr *sum = new Binary(Binary::OperatorKind::Sum, pi, e);
  ArithmeticExpr *lifeUniverseEverything = new Literal(42.0);
  ArithmeticExpr *product = new Binary(Binary::OperatorKind::Product, sum,
                                       lifeUniverseEverything);

  SourceManager sourceMgr;
  DiagnosticEngine diags(sourceMgr);
  Evaluator evaluator(diags,
                      /*debugDumpCycles=*/false,
                      /*buildDependencyGraph=*/true);
  evaluator.registerRequestFunctions(Zone::ArithmeticEvaluator,
                                     arithmeticRequestFunctions);

  const double expectedResult = (3.14159 + 2.71828) * 42.0;
  EXPECT_EQ(evalOrNaN(evaluator, InternallyCachedEvaluationRule(product)),
            expectedResult);

  // Cached response.
  EXPECT_EQ(evalOrNaN(evaluator, InternallyCachedEvaluationRule(product)),
            expectedResult);

  // Uncached
  evaluator.clearCache();
  EXPECT_EQ(evalOrNaN(evaluator, UncachedEvaluationRule(product)),
            expectedResult);
  EXPECT_EQ(evalOrNaN(evaluator, UncachedEvaluationRule(product)),
            expectedResult);

  // External cached query.
  evaluator.clearCache();
  EXPECT_EQ(evalOrNaN(evaluator, ExternallyCachedEvaluationRule(product)),
            expectedResult);
  EXPECT_EQ(*sum->cachedValue, 3.14159 + 2.71828);
  EXPECT_EQ(*product->cachedValue, expectedResult);
  EXPECT_EQ(evalOrNaN(evaluator, ExternallyCachedEvaluationRule(product)),
            expectedResult);
  EXPECT_EQ(*sum->cachedValue, 3.14159 + 2.71828);
  EXPECT_EQ(*product->cachedValue, expectedResult);

  // Dependency printing.

  // Cache some values first, so they show up in the result.
  (void)llvm::cantFail(evaluator(InternallyCachedEvaluationRule(product)),
                       "no explicit cycles were requested");

  std::string productDependencies;
  {
    llvm::raw_string_ostream out(productDependencies);
    evaluator.printDependencies(InternallyCachedEvaluationRule(product), out);
  }

  EXPECT_EQ(productDependencies,
    " `--InternallyCachedEvaluationRule(Binary: product) -> 2.461145e+02\n"
    "     `--InternallyCachedEvaluationRule(Binary: sum) -> 5.859870e+00\n"
    "     |   `--InternallyCachedEvaluationRule(Literal: 3.141590e+00)\n"
    "     |   `--InternallyCachedEvaluationRule(Literal: 2.718280e+00)\n"
    "     `--InternallyCachedEvaluationRule(Literal: 4.200000e+01)\n");

  std::string sumDependencies;
  {
    llvm::raw_string_ostream out(sumDependencies);
    evaluator.printDependencies(ExternallyCachedEvaluationRule(product), out);
  }

  EXPECT_EQ(sumDependencies,
    " `--ExternallyCachedEvaluationRule(Binary: product)\n"
    "     `--ExternallyCachedEvaluationRule(Binary: sum)\n"
    "     |   `--ExternallyCachedEvaluationRule(Literal: 3.141590e+00)\n"
    "     |   `--ExternallyCachedEvaluationRule(Literal: 2.718280e+00)\n"
    "     `--ExternallyCachedEvaluationRule(Literal: 4.200000e+01)\n");

  // Graphviz printing.
  std::string allDependencies;
  {
    llvm::raw_string_ostream out(allDependencies);
    evaluator.printDependenciesGraphviz(out);
  }

  EXPECT_EQ(allDependencies,
    "digraph Dependencies {\n"
    "  request_0 -> request_1;\n"
    "  request_0 -> request_4;\n"
    "  request_1 -> request_3;\n"
    "  request_1 -> request_2;\n"
    "  request_5 -> request_6;\n"
    "  request_5 -> request_9;\n"
    "  request_6 -> request_8;\n"
    "  request_6 -> request_7;\n"
    "  request_10 -> request_11;\n"
    "  request_10 -> request_14;\n"
    "  request_11 -> request_13;\n"
    "  request_11 -> request_12;\n"
    "\n"
    "  request_0 [label=\"ExternallyCachedEvaluationRule(Binary: product)\"];\n"
    "  request_1 [label=\"ExternallyCachedEvaluationRule(Binary: sum)\"];\n"
    "  request_2 [label=\"ExternallyCachedEvaluationRule(Literal: 2.718280e+00)\"];\n"
    "  request_3 [label=\"ExternallyCachedEvaluationRule(Literal: 3.141590e+00)\"];\n"
    "  request_4 [label=\"ExternallyCachedEvaluationRule(Literal: 4.200000e+01)\"];\n"
    "  request_5 [label=\"InternallyCachedEvaluationRule(Binary: product) -> 2.461145e+02\"];\n"
    "  request_6 [label=\"InternallyCachedEvaluationRule(Binary: sum) -> 5.859870e+00\"];\n"
    "  request_7 [label=\"InternallyCachedEvaluationRule(Literal: 2.718280e+00)\"];\n"
    "  request_8 [label=\"InternallyCachedEvaluationRule(Literal: 3.141590e+00)\"];\n"
    "  request_9 [label=\"InternallyCachedEvaluationRule(Literal: 4.200000e+01)\"];\n"
    "  request_10 [label=\"UncachedEvaluationRule(Binary: product)\"];\n"
    "  request_11 [label=\"UncachedEvaluationRule(Binary: sum)\"];\n"
    "  request_12 [label=\"UncachedEvaluationRule(Literal: 2.718280e+00)\"];\n"
    "  request_13 [label=\"UncachedEvaluationRule(Literal: 3.141590e+00)\"];\n"
    "  request_14 [label=\"UncachedEvaluationRule(Literal: 4.200000e+01)\"];\n"
    "}\n");

  // Cleanup
  delete pi;
  delete e;
  delete sum;
  delete lifeUniverseEverything;
  delete product;
}

TEST(ArithmeticEvaluator, Cycle) {
  // (3.14159 + 2.71828) * 42
  ArithmeticExpr *pi = new Literal(3.14159);
  ArithmeticExpr *e = new Literal(2.71828);
  Binary *sum = new Binary(Binary::OperatorKind::Sum, pi, e);
  ArithmeticExpr *lifeUniverseEverything = new Literal(42.0);
  ArithmeticExpr *product = new Binary(Binary::OperatorKind::Product, sum,
                                       lifeUniverseEverything);

  // Introduce a cycle.
  sum->rhs = product;

  SourceManager sourceMgr;
  DiagnosticEngine diags(sourceMgr);
  Evaluator evaluator(diags,
                      /*debugDumpCycles=*/false,
                      /*buildDependencyGraph=*/false);
  evaluator.registerRequestFunctions(Zone::ArithmeticEvaluator,
                                     arithmeticRequestFunctions);

  // Evaluate when there is a cycle.
  UncachedEvaluationRule::brokeCycle = false;
  EXPECT_TRUE(std::isnan(evalOrNaN(evaluator,
                                   UncachedEvaluationRule(product))));
  EXPECT_TRUE(UncachedEvaluationRule::brokeCycle);

  // Cycle-breaking result is cached.
  EXPECT_TRUE(std::isnan(evalOrNaN(evaluator,
                                   UncachedEvaluationRule(product))));
  UncachedEvaluationRule::brokeCycle = false;
  EXPECT_FALSE(UncachedEvaluationRule::brokeCycle);

  // Evaluate when there is a cycle.
  evaluator.clearCache();
  InternallyCachedEvaluationRule::brokeCycle = false;
  EXPECT_TRUE(std::isnan(evalOrNaN(evaluator,
                                   InternallyCachedEvaluationRule(product))));
  EXPECT_TRUE(InternallyCachedEvaluationRule::brokeCycle);

  // Cycle-breaking result is cached.
  InternallyCachedEvaluationRule::brokeCycle = false;
  EXPECT_TRUE(std::isnan(evalOrNaN(evaluator,
                                   InternallyCachedEvaluationRule(product))));
  EXPECT_FALSE(InternallyCachedEvaluationRule::brokeCycle);

  // Evaluate when there is a cycle.
  evaluator.clearCache();
  ExternallyCachedEvaluationRule::brokeCycle = false;
  EXPECT_TRUE(std::isnan(evalOrNaN(evaluator,
                                   ExternallyCachedEvaluationRule(product))));
  EXPECT_TRUE(ExternallyCachedEvaluationRule::brokeCycle);

  // Cycle-breaking result is cached.
  ExternallyCachedEvaluationRule::brokeCycle = false;
  EXPECT_TRUE(std::isnan(evalOrNaN(evaluator,
                                   ExternallyCachedEvaluationRule(product))));
  EXPECT_FALSE(ExternallyCachedEvaluationRule::brokeCycle);

  // Dependency printing.
  std::string productDependencies;
  {
    llvm::raw_string_ostream out(productDependencies);
    evaluator.printDependencies(InternallyCachedEvaluationRule(product), out);
  }

  EXPECT_EQ(productDependencies,
    " `--InternallyCachedEvaluationRule(Binary: product) "
      "(dependency not evaluated)\n");

  // Cleanup
  delete pi;
  delete e;
  delete sum;
  delete lifeUniverseEverything;
  delete product;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: intlwrapper.hxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: er $ $Date: 2001-05-13 03:11:51 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _UNOTOOLS_INTLWRAPPER_HXX
#define _UNOTOOLS_INTLWRAPPER_HXX

#ifndef _UNOTOOLS_CHARCLASS_HXX
#include <unotools/charclass.hxx>
#endif
#ifndef _UNOTOOLS_LOCALEDATAWRAPPER_HXX
#include <unotools/localedatawrapper.hxx>
#endif
#ifndef _UNOTOOLS_CALENDARWRAPPER_HXX
#include <unotools/calendarwrapper.hxx>
#endif
#ifndef _UNOTOOLS_COLLATORWRAPPER_HXX
#include <unotools/collatorwrapper.hxx>
#endif

#ifndef _LANG_HXX
#include <tools/lang.hxx>
#endif

/**
    A wrapper of I18N wrappers. Using this is more expensive than using some
    single wrapper classes so use it only if you must pass a single pointer
    without knowing in advance what is needed, e.g. for
    SfxPoolItem::GetPresentation(). Remember that this wrapper was only created
    for convenience to bypass some oddities, if possible don't use it.

    Implemented are only the const get...() methods of the wrappers, which are
    loaded on demand, for consistency reasons no change of locale is possible.
    Only default calendar and default collator are supported.

    One exception though is the calendar wrapper: to be able to set a value and
    retrieve calendar values it is not const, so methods using this should
    reset the calendar to the previous value if it isn't sure where the
    IntlWrapper did come from.

 */
class IntlWrapper
{
private:

    ::com::sun::star::lang::Locale  aLocale;
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr;

            CharClass*          pCharClass;
            LocaleDataWrapper*  pLocaleData;
            CalendarWrapper*    pCalendar;
            CollatorWrapper*    pCollator;
            CollatorWrapper*    pCaseCollator;

            LanguageType        eLanguage;

            void                ImplNewCharClass() const;
            void                ImplNewLocaleData() const;
            void                ImplNewCalendar() const;
            void                ImplNewCollator( BOOL bCaseSensitive ) const;

public:
                                IntlWrapper(
                                    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xSF,
                                    const ::com::sun::star::lang::Locale& rLocale
                                    );
                                IntlWrapper(
                                    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xSF,
                                    LanguageType eLang
                                    );
                                ~IntlWrapper();

    LanguageType                getLanguage() const { return eLanguage; }
    const ::com::sun::star::lang::Locale&   getLocale() const { return aLocale; }

    const CharClass*            getCharClass() const
                                    {
                                        if ( !pCharClass )
                                            ImplNewCharClass();
                                        return pCharClass;
                                    }
    const LocaleDataWrapper*    getLocaleData() const
                                    {
                                        if ( !pLocaleData )
                                            ImplNewLocaleData();
                                        return pLocaleData;
                                    }
    CalendarWrapper*            getCalendar() const
                                    {
                                        if ( !pCalendar )
                                            ImplNewCalendar();
                                        return pCalendar;
                                    }
    /// case insensitive collator, simple IGNORE_CASE
    const CollatorWrapper*      getCollator() const
                                    {
                                        if ( !pCollator )
                                            ImplNewCollator( FALSE );
                                        return pCollator;
                                    }
    /// case sensitive collator
    const CollatorWrapper*      getCaseCollator() const
                                    {
                                        if ( !pCaseCollator )
                                            ImplNewCollator( TRUE );
                                        return pCaseCollator;
                                    }
};

#endif // _UNOTOOLS_INTLWRAPPER_HXX
<commit_msg>INTEGRATION: CWS visibility03 (1.1.216); FILE MERGED 2005/02/28 04:33:53 mnicel 1.1.216.1: Issue number:  40092 Part of visibility work<commit_after>/*************************************************************************
 *
 *  $RCSfile: intlwrapper.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2005-04-13 12:26:00 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef INCLUDED_UNOTOOLSDLLAPI_H
#include "unotools/unotoolsdllapi.h"
#endif

#ifndef _UNOTOOLS_INTLWRAPPER_HXX
#define _UNOTOOLS_INTLWRAPPER_HXX

#ifndef _UNOTOOLS_CHARCLASS_HXX
#include <unotools/charclass.hxx>
#endif
#ifndef _UNOTOOLS_LOCALEDATAWRAPPER_HXX
#include <unotools/localedatawrapper.hxx>
#endif
#ifndef _UNOTOOLS_CALENDARWRAPPER_HXX
#include <unotools/calendarwrapper.hxx>
#endif
#ifndef _UNOTOOLS_COLLATORWRAPPER_HXX
#include <unotools/collatorwrapper.hxx>
#endif

#ifndef _LANG_HXX
#include <tools/lang.hxx>
#endif

/**
    A wrapper of I18N wrappers. Using this is more expensive than using some
    single wrapper classes so use it only if you must pass a single pointer
    without knowing in advance what is needed, e.g. for
    SfxPoolItem::GetPresentation(). Remember that this wrapper was only created
    for convenience to bypass some oddities, if possible don't use it.

    Implemented are only the const get...() methods of the wrappers, which are
    loaded on demand, for consistency reasons no change of locale is possible.
    Only default calendar and default collator are supported.

    One exception though is the calendar wrapper: to be able to set a value and
    retrieve calendar values it is not const, so methods using this should
    reset the calendar to the previous value if it isn't sure where the
    IntlWrapper did come from.

 */
class UNOTOOLS_DLLPUBLIC IntlWrapper
{
private:

    ::com::sun::star::lang::Locale  aLocale;
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr;

            CharClass*          pCharClass;
            LocaleDataWrapper*  pLocaleData;
            CalendarWrapper*    pCalendar;
            CollatorWrapper*    pCollator;
            CollatorWrapper*    pCaseCollator;

            LanguageType        eLanguage;

            void                ImplNewCharClass() const;
            void                ImplNewLocaleData() const;
            void                ImplNewCalendar() const;
            void                ImplNewCollator( BOOL bCaseSensitive ) const;

public:
                                IntlWrapper(
                                    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xSF,
                                    const ::com::sun::star::lang::Locale& rLocale
                                    );
                                IntlWrapper(
                                    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xSF,
                                    LanguageType eLang
                                    );
                                ~IntlWrapper();

    LanguageType                getLanguage() const { return eLanguage; }
    const ::com::sun::star::lang::Locale&   getLocale() const { return aLocale; }

    const CharClass*            getCharClass() const
                                    {
                                        if ( !pCharClass )
                                            ImplNewCharClass();
                                        return pCharClass;
                                    }
    const LocaleDataWrapper*    getLocaleData() const
                                    {
                                        if ( !pLocaleData )
                                            ImplNewLocaleData();
                                        return pLocaleData;
                                    }
    CalendarWrapper*            getCalendar() const
                                    {
                                        if ( !pCalendar )
                                            ImplNewCalendar();
                                        return pCalendar;
                                    }
    /// case insensitive collator, simple IGNORE_CASE
    const CollatorWrapper*      getCollator() const
                                    {
                                        if ( !pCollator )
                                            ImplNewCollator( FALSE );
                                        return pCollator;
                                    }
    /// case sensitive collator
    const CollatorWrapper*      getCaseCollator() const
                                    {
                                        if ( !pCaseCollator )
                                            ImplNewCollator( TRUE );
                                        return pCaseCollator;
                                    }
};

#endif // _UNOTOOLS_INTLWRAPPER_HXX
<|endoftext|>