<commit_before>// -*-c++-*- function.hpp
// -----------------------------------------------------------------------------
// Copyright 2011 Dietmar Kuehl http://www.dietmar-kuehl.de
// Distributed under the Boost Software License, Version 1.0. (See file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
// -----------------------------------------------------------------------------

#if !defined(UTILS_FUNCTION_HPP)
#define UTILS_FUNCTION_HPP 1
#ident "$Id: function.hpp 141 2011-09-29 18:59:08Z kuehl $"

#include <algorithm>

// -----------------------------------------------------------------------------

namespace utils
{
    template <typename Signature> class function;
    template <typename RC>                                        class function<RC()>;
    template <typename RC, typename T0>                           class function<RC(T0)>;
    template <typename RC, typename T0, typename T1>              class function<RC(T0, T1)>;
    template <typename RC, typename T0, typename T1, typename T2> class function<RC(T0, T1, T2)>;
}

// -----------------------------------------------------------------------------

template <typename RC>
class utils::function<RC()>
{
public:
    template <typename Functor> function(Functor const&);
    function(utils::function<RC()> const&);
    utils::function<RC()>& operator=(utils::function<RC()> const&);
    ~function();
    void swap(utils::function<RC()>&);

    RC operator()() const;

private:
    struct base
    {
        virtual ~base() {}
        virtual base* clone() = 0;
        virtual RC call() = 0;
    }* function_;

    template <typename Functor>
    struct concrete:
        base
    {
        concrete(Functor functor): functor_(functor) {}
        base* clone() { return new concrete<Functor>(*this); }
        RC    call() { return functor_(); }

        Functor functor_;
    };

    template <typename Functor>
    static base* make_function(Functor functor) { return new concrete<Functor>(functor); }
};

// -----------------------------------------------------------------------------

template <typename RC, typename T0>
class utils::function<RC(T0)>
{
public:
    template <typename Functor> function(Functor const&);
    function(utils::function<RC(T0)> const&);
    utils::function<RC(T0)>& operator=(utils::function<RC(T0)> const&);
    ~function();
    void swap(utils::function<RC(T0)>&);

    RC operator()(T0) const;

private:
    struct base
    {
        virtual ~base() {}
        virtual base* clone() = 0;
        virtual RC call(T0) = 0;
    }* function_;

    template <typename Functor>
    struct concrete:
        base
    {
        concrete(Functor functor): functor_(functor) {}
        base* clone() { return new concrete<Functor>(*this); }
        RC    call(T0 a0) { return functor_(a0); }

        Functor functor_;
    };

    template <typename Functor>
    static base* make_function(Functor functor) { return new concrete<Functor>(functor); }
};

// -----------------------------------------------------------------------------

template <typename RC, typename T0, typename T1>
class utils::function<RC(T0, T1)>
{
public:
    template <typename Functor> function(Functor const&);
    function(utils::function<RC(T0, T1)> const&);
    utils::function<RC(T0, T1)>& operator=(utils::function<RC(T0, T1)> const&);
    ~function();
    void swap(utils::function<RC(T0, T1)>&);

    RC operator()(T0, T1) const;

private:
    struct base
    {
        virtual ~base() {}
        virtual base* clone() = 0;
        virtual RC call(T0, T1) = 0;
    }* function_;

    template <typename Functor>
    struct concrete:
        base
    {
        concrete(Functor functor): functor_(functor) {}
        base* clone() { return new concrete<Functor>(*this); }
        RC    call(T0 a0, T1 a1) { return functor_(a0, a1); }

        Functor functor_;
    };

    template <typename Functor>
    static base* make_function(Functor functor) { return new concrete<Functor>(functor); }
};

// -----------------------------------------------------------------------------

template <typename RC, typename T0, typename T1, typename T2>
class utils::function<RC(T0, T1, T2)>
{
public:
    template <typename Functor> function(Functor const&);
    function(utils::function<RC(T0, T1, T2)> const&);
    utils::function<RC(T0, T1, T2)>& operator=(utils::function<RC(T0, T1, T2)> const&);
    ~function();
    void swap(utils::function<RC(T0, T1, T2)>&);

    RC operator()(T0, T1, T2) const;

private:
    struct base
    {
        virtual ~base() {}
        virtual base* clone() = 0;
        virtual RC call(T0, T1, T2) = 0;
    }* function_;

    template <typename Functor>
    struct concrete:
        base
    {
        concrete(Functor functor): functor_(functor) {}
        base* clone() { return new concrete<Functor>(*this); }
        RC    call(T0 a0, T1 a1, T2 a2) { return functor_(a0, a1, a2); }

        Functor functor_;
    };

    template <typename Functor>
    static base* make_function(Functor functor) { return new concrete<Functor>(functor); }
};

// -----------------------------------------------------------------------------

template <typename RC>
template <typename Functor>
utils::function<RC()>::function(Functor const& functor):
    function_(make_function(functor))
{
}

template <typename RC>
utils::function<RC()>::function(utils::function<RC()> const& other):
    function_(other.function_->clone())
{
}

template <typename RC>
utils::function<RC()>&
utils::function<RC()>::operator=(utils::function<RC()> const& other)
{
    utils::function<RC()>(other).swap(*this);
    return *this;
}

template <typename RC>
utils::function<RC()>::~function()
{
    delete function_;
}

template <typename RC>
void utils::function<RC()>::swap(utils::function<RC()>& other)
{
    std::swap(function_, other.function_);
}

template <typename RC>
RC utils::function<RC()>::operator()() const
{
    return function_->call();
}

// -----------------------------------------------------------------------------

template <typename RC, typename T0>
template <typename Functor>
utils::function<RC(T0)>::function(Functor const& functor):
    function_(make_function(functor))
{
}

template <typename RC, typename T0>
utils::function<RC(T0)>::function(utils::function<RC(T0)> const& other):
    function_(other.function_->clone())
{
}

template <typename RC, typename T0>
utils::function<RC(T0)>&
utils::function<RC(T0)>::operator=(utils::function<RC(T0)> const& other)
{
    utils::function<RC(T0)>(other).swap(*this);
    return *this;
}

template <typename RC, typename T0>
utils::function<RC(T0)>::~function()
{
    delete function_;
}

template <typename RC, typename T0>
void utils::function<RC(T0)>::swap(utils::function<RC(T0)>& other)
{
    std::swap(function_, other.function_);
}

template <typename RC, typename T0>
RC utils::function<RC(T0)>::operator()(T0 a0) const
{
    return function_->call(a0);
}

// -----------------------------------------------------------------------------

template <typename RC, typename T0, typename T1>
template <typename Functor>
utils::function<RC(T0, T1)>::function(Functor const& functor):
    function_(make_function(functor))
{
}

template <typename RC, typename T0, typename T1>
utils::function<RC(T0, T1)>::function(utils::function<RC(T0, T1)> const& other):
    function_(other.function_->clone())
{
}

template <typename RC, typename T0, typename T1>
utils::function<RC(T0, T1)>&
utils::function<RC(T0, T1)>::operator=(utils::function<RC(T0, T1)> const& other)
{
    utils::function<RC(T0, T1)>(other).swap(*this);
    return *this;
}

template <typename RC, typename T0, typename T1>
utils::function<RC(T0, T1)>::~function()
{
    delete function_;
}

template <typename RC, typename T0, typename T1>
void utils::function<RC(T0, T1)>::swap(utils::function<RC(T0, T1)>& other)
{
    std::swap(function_, other.function_);
}

template <typename RC, typename T0, typename T1>
RC utils::function<RC(T0, T1)>::operator()(T0 a0, T1 a1) const
{
    return function_->call(a0, a1);
}

// -----------------------------------------------------------------------------

template <typename RC, typename T0, typename T1, typename T2>
template <typename Functor>
utils::function<RC(T0, T1, T2)>::function(Functor const& functor):
    function_(make_function(functor))
{
}

template <typename RC, typename T0, typename T1, typename T2>
utils::function<RC(T0, T1, T2)>::function(utils::function<RC(T0, T1, T2)> const& other):
    function_(other.function_->clone())
{
}

template <typename RC, typename T0, typename T1, typename T2>
utils::function<RC(T0, T1, T2)>&
utils::function<RC(T0, T1, T2)>::operator=(utils::function<RC(T0, T1, T2)> const& other)
{
    utils::function<RC(T0, T1, T2)>(other).swap(*this);
    return *this;
}

template <typename RC, typename T0, typename T1, typename T2>
utils::function<RC(T0, T1, T2)>::~function()
{
    delete function_;
}

template <typename RC, typename T0, typename T1, typename T2>
void utils::function<RC(T0, T1, T2)>::swap(utils::function<RC(T0, T1, T2)>& other)
{
    std::swap(function_, other.function_);
}

template <typename RC, typename T0, typename T1, typename T2>
RC utils::function<RC(T0, T1, T2)>::operator()(T0 a0, T1 a1, T2 a2) const
{
    return function_->call(a0, a1, a2);
}

// -----------------------------------------------------------------------------

#endif /* UTILS_FUNCTION_HPP */
<commit_msg>Use variadic templates.<commit_after>// -*-c++-*- vfunction.hpp
// -----------------------------------------------------------------------------
// Copyright 2011 Dietmar Kuehl http://www.dietmar-kuehl.de
// Distributed under the Boost Software License, Version 1.0. (See file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
// -----------------------------------------------------------------------------

#if !defined(UTILS_FUNCTION_HPP)
#define UTILS_FUNCTION_HPP 1
#ident "$Id$"

#include <algorithm>

// -----------------------------------------------------------------------------

namespace utils
{
    template <typename Signature> class function;
    template <typename RC, typename ...T> class function<RC(T...)>;
}

// -----------------------------------------------------------------------------

template <typename RC, typename ...T>
class utils::function<RC(T...)>
{
public:
    template <typename Functor> function(Functor const&);
    function(utils::function<RC(T...)> const&);
    utils::function<RC(T...)>& operator=(utils::function<RC(T...)> const&);
    ~function();
    void swap(utils::function<RC(T...)>&);

    RC operator()(T...) const;

private:
    struct base
    {
        virtual ~base() {}
        virtual base* clone() = 0;
        virtual RC call(T...) = 0;
    }* function_;

    template <typename Functor>
    struct concrete : base
    {
        concrete(Functor functor): functor_(functor) {}
        base* clone() { return new concrete<Functor>(*this); }
        RC    call(T...a) { return functor_(a...); }

        Functor functor_;
    };

    template <typename Functor>
    static base* make_function(Functor functor)
    {
        return new concrete<Functor>(functor);
    }
};

// -----------------------------------------------------------------------------

template <typename RC, typename ...T>
template <typename Functor>
utils::function<RC(T...)>::function(Functor const& functor):
    function_(make_function(functor))
{
}

template <typename RC, typename ...T>
utils::function<RC(T...)>::function(utils::function<RC(T...)> const& other):
    function_(other.function_->clone())
{
}

template <typename RC, typename ...T>
utils::function<RC(T...)>&
utils::function<RC(T...)>::operator=(utils::function<RC(T...)> const& other)
{
    utils::function<RC(T...)>(other).swap(*this);
    return *this;
}

template <typename RC, typename ...T>
utils::function<RC(T...)>::~function()
{
    delete function_;
}

template <typename RC, typename ...T>
void utils::function<RC(T...)>::swap(utils::function<RC(T...)>& other)
{
    std::swap(function_, other.function_);
}

template <typename RC, typename ...T>
RC utils::function<RC(T...)>::operator()(T...a) const
{
    return function_->call(a...);
}

// -----------------------------------------------------------------------------

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


<commit_before>/* Copyright (c) 2010-present Advanced Micro Devices, Inc.

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE. */

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3128
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>SWDEV-2 - Change OpenCL version number from  3128 to 3129<commit_after>/* Copyright (c) 2010-present Advanced Micro Devices, Inc.

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE. */

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3129
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Created by chord on 16/10/14.
//

#include <TableManager.h>
#include <iostream>
#include <sstream>
#include <BTree/TheBTree.h>
#include <BTree/BTreePlus.h>

using namespace tinydbpp;
using namespace std;
TableManager * TableManager::ins = NULL;
TableManager::Garbo TableManager::garbo;
std::string TableManager::base_dir;
shared_ptr<Pager> TableDescription::getPager(Pager::OpenFlag flag ){
    if(my_pager == nullptr)
        return my_pager = shared_ptr<Pager>(new Pager(path, flag));
    else return my_pager;
}

Item TableDescription::read(char* buf, int len, int& now, bool fixed){
    Item ret;
    int minimum = now + this->len;
    for(int x : pattern){
        if(x > 0){
            BOOST_ASSERT(now + x <= len);
            ret.push_back(std::string(buf + now, x));
            now += x;
        }else if(x == -1){
            BOOST_ASSERT(now + 4 <= len);
            int next_len = *(int*)(buf + now);
            now += 4;
            BOOST_ASSERT(now + next_len <= len);
            ret.push_back(std::string(buf + now, buf + now + next_len));
        }else
            BOOST_ASSERT(0);
    }
    if(fixed && now < minimum)
        now = minimum;
    return ret;
}

void TableDescription::addPattern(int x){
    pattern.push_back(x);
    if(x == -1) len += 4 + DEFAULT_VARCHAR_LEN;
    else len += x;
}
std::string TableDescription::embed(const Item& list, bool & fixed_res){
    std::string ret;
    fixed_res = true;
    for(uint32_t i = 0;i < list.size();i++){
        if(pattern[i] == -1) {
            if (list[i].size() > DEFAULT_VARCHAR_LEN)
                fixed_res = false;
            int len = (int) list[i].length();
            char tmp[4];
            *(int *) tmp = len;
            ret += string(tmp, tmp + 4);
        }
        ret += list[i];
    }
    if(fixed_res)
        ret.resize(len);
    return ret;
}

bool TableDescription::insertInTable(const Item &item) {
    for(int i = 0;i < col_name.size();i++)
    {
        if(col_not_null[i] == 1 && item[i].back() == 1) return false;
        if(col_unique[i] == 1 && item[i].back() != 1 && col_has_index[i] == 1){
            auto res = selectUseIndex(i, item[i]);
            if(res.size() > 0) return false;
        }
    }
    bool fixed_res;
    string rec = embed(item, fixed_res);
    Location loc = RecordManager::getInstance()->insert(name, rec, fixed_res);
    for (int i = 0; i < col_name.size(); i++)
        if (col_has_index[i] == 1) {
            auto index = getIndex(i);
            index->insert(std::hash<string>()(item[i]), TheBTree::BT::locationToString(loc), false);
        }
    return true;
}

std::vector< Item > TableDescription::selectUseIndex(int offset, std::string v, const Checker &checker)
{
    std::vector< Item > ret;
    auto index = getIndex(offset);
    auto vec = index->get(hash<string>()(v));
    for(string & loc : vec) {
        vector<string> item = RecordManager::getInstance()->getEmbedRecord(name, TheBTree::BT::stringToLocation(loc));
        if (v == item[offset] && (checker == nullptr || checker(item)) )
            ret.push_back(item);
    }
    return ret;
}

int TableDescription::getOffset(const std::string & str) {
    for(int i = 0;i < col_name.size();i++)
        if(str == col_name[i])
            return i;
    return -1;
}

std::shared_ptr<TheBTree> TableDescription::getIndex(int offset) {
    return make_shared<TheBTree>(TableManager::createIndexName(name, col_name[offset]));
}

void TableDescription::updateItems(Checker &checker, Changer &changer) {
    auto pre = deleteAndCollectItems(checker);
    for(auto & item : pre) {
        changer(item);
        insertInTable(item);
    }
}

std::vector<Item > TableDescription::deleteAndCollectItems(const Checker & checker) {
    auto td = this;
    vector<Item > ret;
    std::function<void(const Item&, Location)> solver = [td, &ret](const Item& item, Location loc){
        ret.push_back(item);
        string loc_data = TheBTree::BT::locationToString(loc);
        for(int i = 0;i < td->col_has_index.size();i++)
            if(td->col_has_index[i] == 1){
                auto index = td->getIndex(i);
                index->remove(hash<string>()(item[i]), [&loc_data](const std::string & s){
                    return s == loc_data;
                }, false);
            }
    };
    RecordManager::getInstance()->del(name, checker, solver);
    return ret;
}

std::vector<Item> TableDescription::deleteAndCollectUseIndex(int offset, std::string v, const Checker &checker) {
    std::vector< Item > ret;
    auto index = getIndex(offset);
    auto vec = index->get(hash<string>()(v));
    vector<string> correct_loc;
    for(string & loc : vec) {
        vector<string> item = RecordManager::getInstance()->getEmbedRecord(name, TheBTree::BT::stringToLocation(loc));
        if (v == item[offset] && (checker == nullptr || checker(item)) ){
            ret.push_back(item);
            correct_loc.push_back(loc);
            RecordManager::getInstance()->deleteRecord(name, TheBTree::BT::stringToLocation(loc));
        }
    }
    index->remove(hash<string>()(v),[&correct_loc](const std::string & s){
        for(auto & loc : correct_loc)
            if(loc == s) return true;
        return false;
    }, false);
    return ret;
}

std::vector< Item > TableDescription::selectUseChecker(Checker &checker)
{
    vector<Item > ret;
    std::function<void( Item&, int, int)> solver = [&ret]( Item& item, int, int){
        ret.push_back(item);
    };
    RecordManager::getInstance()->select(name,checker,solver);
    return ret;
}

std::shared_ptr<TableDescription> TableManager::getTableDescription(std::string name) {
    for(auto ptr : table_map)
        if(ptr->name == name)
            return ptr;
    if(!FileUtils::isExist((dir + "/" + name).c_str()))
        return nullptr;
    shared_ptr<TableDescription> ret(new TableDescription());
    ret->name = name;
    ret->path = dir + "/" + name;
    auto parse_func = [this, &name](shared_ptr<TableDescription> new_td){
        //0.this function should be implemented in parser module, this is a test func
        //1.read from page(0) in new_td->getPager()->getPage(0) and parse
        //2.add bytes pattern of new_td;
        //3.if necessary add other properties in TableDescription class(whether there is a index)
        auto p = new_td->getPager()->getPage(0);
        char* buf = p->getBuf();
        istringstream istr;
        istr.str(buf);
        int num;
        istr >> num;
        for(int i = 0;i < num;i++)
        {
            string colName,t;
            int pat, b1, b2, w;
            istr >> colName >> t >> pat >> b1 >> b2 >> w;
            new_td->col_name.push_back(colName);
            new_td->col_type.push_back(t);
            new_td->addPattern(pat);
            new_td->col_not_null.push_back(b1);
            new_td->col_unique.push_back(b2);
            new_td->col_width.push_back(w);
            // DONE check has index
            FileUtils fileUtils;
            int hasIndex = fileUtils.isExist((dir + "/" + createIndexName(name, colName)).c_str());
            new_td->col_has_index.push_back(hasIndex);
        }
        p->releaseBuf(buf);
    };
    if(name.find("_") == string::npos)// not index "table"
        parse_func(ret);
    table_map.push_back(ret);
    return ret;
}

bool TableManager::changeDB(std::string db, bool auto_create) {
    if(db == dbname)
        return true;
    string dbtable_name = this->base_dir + "/" + db + "/" + SYS_TABLE_NAME;
    if(!FileUtils::isExist(dbtable_name.c_str())) {
        if (!auto_create)
            return false;
        else
            FileUtils::createFile(dbtable_name.c_str());
    }
    this->dbname = db;
    this->dir = this->base_dir + "/" + db;
    table_map.clear();
    return true;
}

void TableManager::createDB(std::string db) {
    string dbtable_name = this->base_dir + "/" + db + "/" + SYS_TABLE_NAME;
    if(!FileUtils::isExist(dbtable_name.c_str()))
            FileUtils::createFile(dbtable_name.c_str());
}

bool TableManager::DropDB(std::string db) {
    if(dbname == db){
        dbname = "";
        table_map.clear();
    }
    return FileUtils::deleteDir((this->base_dir + "/" + db).c_str());
}

bool TableManager::buildTable(std::string name, std::function<void(Pager *)> callback) {
    string whole_name = dir + "/" + name;
    if(FileUtils::isExist(whole_name.c_str()))
        return false;
    else{
        shared_ptr<Pager> ptr( new Pager(whole_name, Pager::ReadWrite) );
        if (callback) {
            callback(ptr.get());
        }
        ptr->writeBackAll();
        return true;
    }
}

std::string TableManager::createIndexName(const std::string &tableName, const std::string &colName) {
    return tableName + "_" + colName;
}

bool TableManager::parseIndex(const std::string &indexName, const std::string &tableName, std::string &colName) {
    if (indexName.size() > tableName.size() && indexName.substr(0, tableName.size()) == tableName) {
        colName = indexName.substr(tableName.size() + 1, indexName.size() - (tableName.size() + 1));
        return true;
    }
    return false;
}

bool TableManager::dropTable(std::string name) {
    for(auto iter = table_map.begin();iter != table_map.end();)
        if((*iter)->name == name || ((*iter)->name).find(name + "_") != string::npos)
            table_map.erase(iter++);
        else iter ++;

    auto files = FileUtils::listFiles(dir.c_str());
    bool ret = false;
    for(auto & f : files)
        if(f == name || f.find(name + "_") != string::npos) {
            FileUtils::deleteFile((dir + "/" + f).c_str());
            ret = true;
        }
    return ret;
}
<commit_msg>fix read bug<commit_after>//
// Created by chord on 16/10/14.
//

#include <TableManager.h>
#include <iostream>
#include <sstream>
#include <BTree/TheBTree.h>
#include <BTree/BTreePlus.h>

using namespace tinydbpp;
using namespace std;
TableManager * TableManager::ins = NULL;
TableManager::Garbo TableManager::garbo;
std::string TableManager::base_dir;
shared_ptr<Pager> TableDescription::getPager(Pager::OpenFlag flag ){
    if(my_pager == nullptr)
        return my_pager = shared_ptr<Pager>(new Pager(path, flag));
    else return my_pager;
}

Item TableDescription::read(char* buf, int len, int& now, bool fixed){
    Item ret;
    int minimum = now + this->len;
    for(int x : pattern){
        if(x > 0){
            BOOST_ASSERT(now + x <= len);
            ret.push_back(std::string(buf + now, x));
            now += x;
        }else if(x == -1){
            BOOST_ASSERT(now + 4 <= len);
            int next_len = *(int*)(buf + now);
            now += 4;
            BOOST_ASSERT(now + next_len <= len);
            ret.push_back(std::string(buf + now, buf + now + next_len));
            now += next_len;
        }else
            BOOST_ASSERT(0);
    }
    if(fixed && now < minimum)
        now = minimum;
    return ret;
}

void TableDescription::addPattern(int x){
    pattern.push_back(x);
    if(x == -1) len += 4 + DEFAULT_VARCHAR_LEN;
    else len += x;
}
std::string TableDescription::embed(const Item& list, bool & fixed_res){
    std::string ret;
    fixed_res = true;
    for(uint32_t i = 0;i < list.size();i++){
        if(pattern[i] == -1) {
            if (list[i].size() > DEFAULT_VARCHAR_LEN)
                fixed_res = false;
            int len = (int) list[i].length();
            char tmp[4];
            *(int *) tmp = len;
            ret += string(tmp, tmp + 4);
        }
        ret += list[i];
    }
    if(fixed_res)
        ret.resize(len);
    return ret;
}

bool TableDescription::insertInTable(const Item &item) {
    for(int i = 0;i < col_name.size();i++)
    {
        if(col_not_null[i] == 1 && item[i].back() == 1) return false;
        if(col_unique[i] == 1 && item[i].back() != 1 && col_has_index[i] == 1){
            auto res = selectUseIndex(i, item[i]);
            if(res.size() > 0) return false;
        }
    }
    bool fixed_res;
    string rec = embed(item, fixed_res);
    Location loc = RecordManager::getInstance()->insert(name, rec, fixed_res);
    for (int i = 0; i < col_name.size(); i++)
        if (col_has_index[i] == 1) {
            auto index = getIndex(i);
            index->insert(std::hash<string>()(item[i]), TheBTree::BT::locationToString(loc), false);
        }
    return true;
}

std::vector< Item > TableDescription::selectUseIndex(int offset, std::string v, const Checker &checker)
{
    std::vector< Item > ret;
    auto index = getIndex(offset);
    auto vec = index->get(hash<string>()(v));
    for(string & loc : vec) {
        vector<string> item = RecordManager::getInstance()->getEmbedRecord(name, TheBTree::BT::stringToLocation(loc));
        if (v == item[offset] && (checker == nullptr || checker(item)) )
            ret.push_back(item);
    }
    return ret;
}

int TableDescription::getOffset(const std::string & str) {
    for(int i = 0;i < col_name.size();i++)
        if(str == col_name[i])
            return i;
    return -1;
}

std::shared_ptr<TheBTree> TableDescription::getIndex(int offset) {
    return make_shared<TheBTree>(TableManager::createIndexName(name, col_name[offset]));
}

void TableDescription::updateItems(Checker &checker, Changer &changer) {
    auto pre = deleteAndCollectItems(checker);
    for(auto & item : pre) {
        changer(item);
        insertInTable(item);
    }
}

std::vector<Item > TableDescription::deleteAndCollectItems(const Checker & checker) {
    auto td = this;
    vector<Item > ret;
    std::function<void(const Item&, Location)> solver = [td, &ret](const Item& item, Location loc){
        ret.push_back(item);
        string loc_data = TheBTree::BT::locationToString(loc);
        for(int i = 0;i < td->col_has_index.size();i++)
            if(td->col_has_index[i] == 1){
                auto index = td->getIndex(i);
                index->remove(hash<string>()(item[i]), [&loc_data](const std::string & s){
                    return s == loc_data;
                }, false);
            }
    };
    RecordManager::getInstance()->del(name, checker, solver);
    return ret;
}

std::vector<Item> TableDescription::deleteAndCollectUseIndex(int offset, std::string v, const Checker &checker) {
    std::vector< Item > ret;
    auto index = getIndex(offset);
    auto vec = index->get(hash<string>()(v));
    vector<string> correct_loc;
    for(string & loc : vec) {
        vector<string> item = RecordManager::getInstance()->getEmbedRecord(name, TheBTree::BT::stringToLocation(loc));
        if (v == item[offset] && (checker == nullptr || checker(item)) ){
            ret.push_back(item);
            correct_loc.push_back(loc);
            RecordManager::getInstance()->deleteRecord(name, TheBTree::BT::stringToLocation(loc));
        }
    }
    index->remove(hash<string>()(v),[&correct_loc](const std::string & s){
        for(auto & loc : correct_loc)
            if(loc == s) return true;
        return false;
    }, false);
    return ret;
}

std::vector< Item > TableDescription::selectUseChecker(Checker &checker)
{
    vector<Item > ret;
    std::function<void( Item&, int, int)> solver = [&ret]( Item& item, int, int){
        ret.push_back(item);
    };
    RecordManager::getInstance()->select(name,checker,solver);
    return ret;
}

std::shared_ptr<TableDescription> TableManager::getTableDescription(std::string name) {
    for(auto ptr : table_map)
        if(ptr->name == name)
            return ptr;
    if(!FileUtils::isExist((dir + "/" + name).c_str()))
        return nullptr;
    shared_ptr<TableDescription> ret(new TableDescription());
    ret->name = name;
    ret->path = dir + "/" + name;
    auto parse_func = [this, &name](shared_ptr<TableDescription> new_td){
        //0.this function should be implemented in parser module, this is a test func
        //1.read from page(0) in new_td->getPager()->getPage(0) and parse
        //2.add bytes pattern of new_td;
        //3.if necessary add other properties in TableDescription class(whether there is a index)
        auto p = new_td->getPager()->getPage(0);
        char* buf = p->getBuf();
        istringstream istr;
        istr.str(buf);
        int num;
        istr >> num;
        for(int i = 0;i < num;i++)
        {
            string colName,t;
            int pat, b1, b2, w;
            istr >> colName >> t >> pat >> b1 >> b2 >> w;
            new_td->col_name.push_back(colName);
            new_td->col_type.push_back(t);
            new_td->addPattern(pat);
            new_td->col_not_null.push_back(b1);
            new_td->col_unique.push_back(b2);
            new_td->col_width.push_back(w);
            // DONE check has index
            FileUtils fileUtils;
            int hasIndex = fileUtils.isExist((dir + "/" + createIndexName(name, colName)).c_str());
            new_td->col_has_index.push_back(hasIndex);
        }
        p->releaseBuf(buf);
    };
    if(name.find("_") == string::npos)// not index "table"
        parse_func(ret);
    table_map.push_back(ret);
    return ret;
}

bool TableManager::changeDB(std::string db, bool auto_create) {
    if(db == dbname)
        return true;
    string dbtable_name = this->base_dir + "/" + db + "/" + SYS_TABLE_NAME;
    if(!FileUtils::isExist(dbtable_name.c_str())) {
        if (!auto_create)
            return false;
        else
            FileUtils::createFile(dbtable_name.c_str());
    }
    this->dbname = db;
    this->dir = this->base_dir + "/" + db;
    table_map.clear();
    return true;
}

void TableManager::createDB(std::string db) {
    string dbtable_name = this->base_dir + "/" + db + "/" + SYS_TABLE_NAME;
    if(!FileUtils::isExist(dbtable_name.c_str()))
            FileUtils::createFile(dbtable_name.c_str());
}

bool TableManager::DropDB(std::string db) {
    if(dbname == db){
        dbname = "";
        table_map.clear();
    }
    return FileUtils::deleteDir((this->base_dir + "/" + db).c_str());
}

bool TableManager::buildTable(std::string name, std::function<void(Pager *)> callback) {
    string whole_name = dir + "/" + name;
    if(FileUtils::isExist(whole_name.c_str()))
        return false;
    else{
        shared_ptr<Pager> ptr( new Pager(whole_name, Pager::ReadWrite) );
        if (callback) {
            callback(ptr.get());
        }
        ptr->writeBackAll();
        return true;
    }
}

std::string TableManager::createIndexName(const std::string &tableName, const std::string &colName) {
    return tableName + "_" + colName;
}

bool TableManager::parseIndex(const std::string &indexName, const std::string &tableName, std::string &colName) {
    if (indexName.size() > tableName.size() && indexName.substr(0, tableName.size()) == tableName) {
        colName = indexName.substr(tableName.size() + 1, indexName.size() - (tableName.size() + 1));
        return true;
    }
    return false;
}

bool TableManager::dropTable(std::string name) {
    for(auto iter = table_map.begin();iter != table_map.end();)
        if((*iter)->name == name || ((*iter)->name).find(name + "_") != string::npos)
            table_map.erase(iter++);
        else iter ++;

    auto files = FileUtils::listFiles(dir.c_str());
    bool ret = false;
    for(auto & f : files)
        if(f == name || f.find(name + "_") != string::npos) {
            FileUtils::deleteFile((dir + "/" + f).c_str());
            ret = true;
        }
    return ret;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: drawingmltypes.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "oox/drawingml/drawingmltypes.hxx"

#include <com/sun/star/awt/FontPitch.hpp>
#include <com/sun/star/awt/FontUnderline.hpp>
#include <com/sun/star/awt/FontFamily.hpp>
#include <com/sun/star/awt/FontStrikeout.hpp>
#include <com/sun/star/style/TabAlign.hpp>
#include <com/sun/star/style/CaseMap.hpp>
#include <com/sun/star/style/ParagraphAdjust.hpp>

#include <sax/tools/converter.hxx>
#include "oox/helper/attributelist.hxx"
#include "oox/core/namespaces.hxx"
#include "oox/drawingml/shape.hxx"
#include "tokens.hxx"

using ::rtl::OUString;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::style;
using namespace ::oox::core;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;

namespace oox { namespace drawingml {

// --------------------------------------------------------------------

/** converts an emu string into 1/100th mmm but constrain as per ST_TextMargin
 * see 5.1.12.73
 */
sal_Int32 GetTextMargin( const ::rtl::OUString& sValue )
{
    sal_Int32 nRet = 0;
    if( !::sax::Converter::convertNumber( nRet, sValue ) )
        nRet = 0;
    else if( nRet < 0 )
        nRet = 0;
    else if( nRet > 51206400 )
        nRet = 51206400;

    nRet /= 360;
    return nRet;
}

/** converts an emu string into 1/100th mmm */
sal_Int32 GetCoordinate( const ::rtl::OUString& sValue )
{
    sal_Int32 nRet = 0;
    if( !::sax::Converter::convertNumber( nRet, sValue ) )
        nRet = 0;

    nRet /= 360;
    return nRet;
}

/** converts a ST_Percentage % string into 1/1000th of % */
sal_Int32 GetPercent( const ::rtl::OUString& sValue )
{
    sal_Int32 nRet = 0;
    if( !::sax::Converter::convertNumber( nRet, sValue ) )
        nRet = 0;

    return nRet;
}

double GetPositiveFixedPercentage( const ::rtl::OUString& sValue )
{
    double fPercent = sValue.toFloat() / 100000.;
    return fPercent;
}

// --------------------------------------------------------------------

/** converts the attributes from an CT_Point2D into an awt Point with 1/100thmm */
::com::sun::star::awt::Point GetPoint2D( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs )
{
    return ::com::sun::star::awt::Point( GetCoordinate( xAttribs->getOptionalValue( XML_x ) ), GetCoordinate( xAttribs->getOptionalValue( XML_y ) ) );
}

/** converts the attributes from an CT_TLPoint into an awt Point with 1/1000% */
::com::sun::star::awt::Point GetPointPercent( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs )
{
    return ::com::sun::star::awt::Point( GetPercent( xAttribs->getOptionalValue( XML_x ) ), GetCoordinate( xAttribs->getOptionalValue( XML_y ) ) );
}

// --------------------------------------------------------------------

/** converts the ST_TextFontSize to point */
float GetTextSize( const ::rtl::OUString& sValue )
{
    float fRet = 0;
    sal_Int32 nRet;
    if( ::sax::Converter::convertNumber( nRet, sValue ) )
        fRet = static_cast< float >( static_cast< double >( nRet ) / 100.0 );
    return fRet;
}

/** converts the ST_TextSpacingPoint to 1/100mm */
sal_Int32 GetTextSpacingPoint( const ::rtl::OUString& sValue )
{
    sal_Int32 nRet;
    if( ::sax::Converter::convertNumber( nRet, sValue ) )
        nRet = ( nRet * 254 + 360 ) / 720;
    return nRet;
}

sal_Int16 GetFontUnderline( ::sal_Int32 nToken )
{
    sal_Int16 nEnum;
    switch( nToken )
    {
    case XML_none:
        nEnum = FontUnderline::NONE;
        break;
    case XML_dash:
        nEnum = FontUnderline::DASH;
        break;
    case XML_dashHeavy:
        nEnum = FontUnderline::BOLDDASH;
        break;
    case XML_dashLong:
        nEnum = FontUnderline::LONGDASH;
        break;
    case XML_dashLongHeavy:
        nEnum = FontUnderline::BOLDLONGDASH;
        break;
    case XML_dbl:
        nEnum = FontUnderline::DOUBLE;
        break;
    case XML_dotDash:
        nEnum = FontUnderline::DASHDOT;
        break;
    case XML_dotDashHeavy:
        nEnum = FontUnderline::BOLDDASHDOT;
        break;
    case XML_dotDotDash:
        nEnum = FontUnderline::DASHDOTDOT;
        break;
    case XML_dotDotDashHeavy:
        nEnum = FontUnderline::BOLDDASHDOTDOT;
        break;
    case XML_dotted:
        nEnum = FontUnderline::DOTTED;
        break;
    case XML_dottedHeavy:
        nEnum = FontUnderline::BOLDDOTTED;
        break;
    case XML_heavy:
        nEnum = FontUnderline::BOLD;
        break;
    case XML_sng:
        nEnum = FontUnderline::SINGLE;
        break;
    case XML_wavy:
        nEnum = FontUnderline::WAVE;
        break;
    case XML_wavyDbl:
        nEnum = FontUnderline::DOUBLEWAVE;
        break;
    case XML_wavyHeavy:
         nEnum = FontUnderline::BOLDWAVE;
        break;
    case XML_words:
        // TODO
    default:
        nEnum = FontUnderline::DONTKNOW;
        break;
    }
    return nEnum;
}

sal_Int16 GetFontStrikeout( sal_Int32 nToken )
{
    sal_Int16 nEnum;
    switch( nToken )
    {
    case XML_dblStrike:
        nEnum = FontStrikeout::DOUBLE;
        break;
    case XML_noStrike:
        nEnum = FontStrikeout::NONE;
        break;
    case XML_sngStrike:
        nEnum = FontStrikeout::SINGLE;
        break;
    default:
        nEnum = FontStrikeout::DONTKNOW;
        break;
    }
    return nEnum;
}

sal_Int16 GetCaseMap( sal_Int32 nToken )
{
    sal_Int16 nEnum;
    switch( nToken )
    {
    case XML_all:
        nEnum = CaseMap::UPPERCASE;
        break;
    case XML_small:
        nEnum = CaseMap::SMALLCAPS;
        break;
    case XML_none:
        // fall through
    default:
        nEnum = CaseMap::NONE;
        break;
    }
    return nEnum;
}

// BEGIN stolen from sd/source/filter/eppt/epptso.cxx
/* Font Families */
#define FF_DONTCARE             0x00
#define FF_ROMAN                0x10
#define FF_SWISS                0x20
#define FF_MODERN               0x30
#define FF_SCRIPT               0x40
#define FF_DECORATIVE           0x50

/* Font pitches */
#define DEFAULT_PITCH           0x00
#define FIXED_PITCH             0x01
#define VARIABLE_PITCH          0x02

// END

void GetFontPitch( sal_Int32 nOoxValue, sal_Int16 & nPitch, sal_Int16 & nFamily )
{
    sal_Int32 oFamily = ( nOoxValue & 0xf0 );
    sal_Int32 oPitch = ( nOoxValue & 0x0f );
    switch( oFamily )
    {
    case FF_ROMAN:
        nFamily = FontFamily::ROMAN;
        break;
    case FF_SWISS:
        nFamily = FontFamily::SWISS;
        break;
    case FF_MODERN:
        nFamily = FontFamily::MODERN;
        break;
    case FF_SCRIPT:
        nFamily = FontFamily::SCRIPT;
        break;
    case FF_DECORATIVE:
        nFamily = FontFamily::DECORATIVE;
        break;
    default:
        nFamily = FontFamily::DONTKNOW;
        break;
    }
    switch( oPitch )
    {
    case FIXED_PITCH:
        nPitch = FontPitch::FIXED;
        break;
    case VARIABLE_PITCH:
        nPitch = FontPitch::VARIABLE;
        break;
    case DEFAULT_PITCH:
    default:
        nPitch = FontPitch::DONTKNOW;
        break;
    }
}

/** converts a paragraph align to a ParaAdjust */
sal_Int16 GetParaAdjust( sal_Int32 nAlign )
{
    sal_Int16 nEnum;
    switch( nAlign )
    {
    case XML_ctr:
        nEnum = ParagraphAdjust_CENTER;
        break;
    case XML_just:
    case XML_justLow:
        nEnum = ParagraphAdjust_BLOCK;
        break;
    case XML_r:
        nEnum = ParagraphAdjust_RIGHT;
        break;
    case XML_thaiDist:
    case XML_dist:
        nEnum = ParagraphAdjust_STRETCH;
        break;
    case XML_l:
    default:
        nEnum = ParagraphAdjust_LEFT;
        break;
    }
    return nEnum;
}

TabAlign GetTabAlign( sal_Int32 aToken )
{
    TabAlign nEnum;
    switch( aToken )
    {
    case XML_ctr:
        nEnum = TabAlign_CENTER;
        break;
    case XML_dec:
        nEnum = TabAlign_DECIMAL;
        break;
    case XML_l:
        nEnum = TabAlign_LEFT;
        break;
    case XML_r:
        nEnum = TabAlign_RIGHT;
        break;
    default:
        nEnum = TabAlign_DEFAULT;
        break;
    }
    return nEnum;
}

// --------------------------------------------------------------------

/** converts the attributes from a CT_RelativeRect to an IntegerRectangle2D */
com::sun::star::geometry::IntegerRectangle2D GetRelativeRect( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs )
{
    com::sun::star::geometry::IntegerRectangle2D r;

    r.X1 = xAttribs->getOptionalValue( XML_l ).toInt32();
    r.Y1 = xAttribs->getOptionalValue( XML_t ).toInt32();
    r.X2 = xAttribs->getOptionalValue( XML_r ).toInt32();
    r.Y2 = xAttribs->getOptionalValue( XML_b ).toInt32();

    return r;
}

// --------------------------------------------------------------------

/** converts the attributes from an CT_Size2D into an awt Size with 1/100thmm */
::com::sun::star::awt::Size GetSize2D( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs )
{
    return ::com::sun::star::awt::Size( GetCoordinate( xAttribs->getOptionalValue( XML_cx ) ), GetCoordinate( xAttribs->getOptionalValue( XML_cy ) ) );
}

IndexRange GetIndexRange( const Reference< XFastAttributeList >& xAttributes )
{
    IndexRange range;
    range.start = xAttributes->getOptionalValue( XML_st ).toInt32();
    range.end = xAttributes->getOptionalValue( XML_end ).toInt32();
    return range;
}

// --------------------------------------------------------------------

/** context to import a CT_Transform2D */
Transform2DContext::Transform2DContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, Shape& rShape ) throw()
: ContextHandler( rParent )
, mrShape( rShape )
{
    AttributeList aAttributeList( xAttribs );
    mrShape.setRotation( aAttributeList.getInteger( XML_rot, 0 ) ); // 60000ths of a degree Positive angles are clockwise; negative angles are counter-clockwise
    mrShape.setFlip( aAttributeList.getBool( XML_flipH, sal_False ), aAttributeList.getBool( XML_flipV, sal_False ) );
}

void Transform2DContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
{
}

Reference< XFastContextHandler > Transform2DContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
{
    switch( aElementToken )
    {
    case NMSP_DRAWINGML|XML_off:        // horz/vert translation
        mrShape.setPosition( Point( xAttribs->getOptionalValue( XML_x ).toInt32(), xAttribs->getOptionalValue( XML_y ).toInt32() ) );
        break;
    case NMSP_DRAWINGML|XML_ext:        // horz/vert size
        mrShape.setSize( Size( xAttribs->getOptionalValue( XML_cx ).toInt32(), xAttribs->getOptionalValue( XML_cy ).toInt32() ) );
        break;
/* todo: what to do?
    case NMSP_DRAWINGML|XML_chOff:  // horz/vert translation of children
    case NMSP_DRAWINGML|XML_chExt:  // horz/vert size of children
        break;
*/
    }

    Reference< XFastContextHandler > xEmpty;
    return xEmpty;
}

} }
<commit_msg>INTEGRATION: CWS xmlfilter05 (1.3.4); FILE MERGED 2008/05/02 11:16:31 hbrinkm 1.3.4.4: RESYNC: (1.3-1.4); FILE MERGED 2008/04/25 08:57:33 dr 1.3.4.3: more cleanup 2008/04/02 12:41:55 hbrinkm 1.3.4.2: merged changes from xmlfilter04 to xmlfilter05 2008/04/01 15:38:02 hbrinkm 1.3.4.1: 'Merged xmlfilter04'<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: drawingmltypes.cxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "oox/drawingml/drawingmltypes.hxx"
#include <com/sun/star/awt/FontPitch.hpp>
#include <com/sun/star/awt/FontUnderline.hpp>
#include <com/sun/star/awt/FontFamily.hpp>
#include <com/sun/star/awt/FontStrikeout.hpp>
#include <com/sun/star/style/CaseMap.hpp>
#include <com/sun/star/style/ParagraphAdjust.hpp>
#include <sax/tools/converter.hxx>
#include "tokens.hxx"

using ::rtl::OUString;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::xml::sax::XFastAttributeList;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::geometry;

namespace oox { namespace drawingml {

// --------------------------------------------------------------------

/** converts an emu string into 1/100th mmm but constrain as per ST_TextMargin
 * see 5.1.12.73
 */
sal_Int32 GetTextMargin( const OUString& sValue )
{
    sal_Int32 nRet = 0;
    if( !::sax::Converter::convertNumber( nRet, sValue ) )
        nRet = 0;
    else if( nRet < 0 )
        nRet = 0;
    else if( nRet > 51206400 )
        nRet = 51206400;

    nRet /= 360;
    return nRet;
}

/** converts an emu string into 1/100th mmm */
sal_Int32 GetCoordinate( const OUString& sValue )
{
    sal_Int32 nRet = 0;
    if( !::sax::Converter::convertNumber( nRet, sValue ) )
        nRet = 0;

    nRet /= 360;
    return nRet;
}

/** converts a ST_Percentage % string into 1/1000th of % */
sal_Int32 GetPercent( const OUString& sValue )
{
    sal_Int32 nRet = 0;
    if( !::sax::Converter::convertNumber( nRet, sValue ) )
        nRet = 0;

    return nRet;
}

double GetPositiveFixedPercentage( const OUString& sValue )
{
    double fPercent = sValue.toFloat() / 100000.;
    return fPercent;
}

// --------------------------------------------------------------------

/** converts the attributes from an CT_Point2D into an awt Point with 1/100thmm */
Point GetPoint2D( const Reference< XFastAttributeList >& xAttribs )
{
    return Point( GetCoordinate( xAttribs->getOptionalValue( XML_x ) ), GetCoordinate( xAttribs->getOptionalValue( XML_y ) ) );
}

/** converts the attributes from an CT_TLPoint into an awt Point with 1/1000% */
Point GetPointPercent( const Reference< XFastAttributeList >& xAttribs )
{
    return Point( GetPercent( xAttribs->getOptionalValue( XML_x ) ), GetCoordinate( xAttribs->getOptionalValue( XML_y ) ) );
}

// --------------------------------------------------------------------

/** converts the ST_TextFontSize to point */
float GetTextSize( const OUString& sValue )
{
    float fRet = 0;
    sal_Int32 nRet;
    if( ::sax::Converter::convertNumber( nRet, sValue ) )
        fRet = static_cast< float >( static_cast< double >( nRet ) / 100.0 );
    return fRet;
}

/** converts the ST_TextSpacingPoint to 1/100mm */
sal_Int32 GetTextSpacingPoint( const OUString& sValue )
{
    sal_Int32 nRet;
    if( ::sax::Converter::convertNumber( nRet, sValue ) )
        nRet = ( nRet * 254 + 360 ) / 720;
    return nRet;
}

sal_Int16 GetFontUnderline( ::sal_Int32 nToken )
{
    sal_Int16 nEnum;
    switch( nToken )
    {
    case XML_none:
        nEnum = FontUnderline::NONE;
        break;
    case XML_dash:
        nEnum = FontUnderline::DASH;
        break;
    case XML_dashHeavy:
        nEnum = FontUnderline::BOLDDASH;
        break;
    case XML_dashLong:
        nEnum = FontUnderline::LONGDASH;
        break;
    case XML_dashLongHeavy:
        nEnum = FontUnderline::BOLDLONGDASH;
        break;
    case XML_dbl:
        nEnum = FontUnderline::DOUBLE;
        break;
    case XML_dotDash:
        nEnum = FontUnderline::DASHDOT;
        break;
    case XML_dotDashHeavy:
        nEnum = FontUnderline::BOLDDASHDOT;
        break;
    case XML_dotDotDash:
        nEnum = FontUnderline::DASHDOTDOT;
        break;
    case XML_dotDotDashHeavy:
        nEnum = FontUnderline::BOLDDASHDOTDOT;
        break;
    case XML_dotted:
        nEnum = FontUnderline::DOTTED;
        break;
    case XML_dottedHeavy:
        nEnum = FontUnderline::BOLDDOTTED;
        break;
    case XML_heavy:
        nEnum = FontUnderline::BOLD;
        break;
    case XML_sng:
        nEnum = FontUnderline::SINGLE;
        break;
    case XML_wavy:
        nEnum = FontUnderline::WAVE;
        break;
    case XML_wavyDbl:
        nEnum = FontUnderline::DOUBLEWAVE;
        break;
    case XML_wavyHeavy:
         nEnum = FontUnderline::BOLDWAVE;
        break;
    case XML_words:
        // TODO
    default:
        nEnum = FontUnderline::DONTKNOW;
        break;
    }
    return nEnum;
}

sal_Int16 GetFontStrikeout( sal_Int32 nToken )
{
    sal_Int16 nEnum;
    switch( nToken )
    {
    case XML_dblStrike:
        nEnum = FontStrikeout::DOUBLE;
        break;
    case XML_noStrike:
        nEnum = FontStrikeout::NONE;
        break;
    case XML_sngStrike:
        nEnum = FontStrikeout::SINGLE;
        break;
    default:
        nEnum = FontStrikeout::DONTKNOW;
        break;
    }
    return nEnum;
}

sal_Int16 GetCaseMap( sal_Int32 nToken )
{
    sal_Int16 nEnum;
    switch( nToken )
    {
    case XML_all:
        nEnum = CaseMap::UPPERCASE;
        break;
    case XML_small:
        nEnum = CaseMap::SMALLCAPS;
        break;
    case XML_none:
        // fall through
    default:
        nEnum = CaseMap::NONE;
        break;
    }
    return nEnum;
}

// BEGIN stolen from sd/source/filter/eppt/epptso.cxx
/* Font Families */
#define FF_DONTCARE             0x00
#define FF_ROMAN                0x10
#define FF_SWISS                0x20
#define FF_MODERN               0x30
#define FF_SCRIPT               0x40
#define FF_DECORATIVE           0x50

/* Font pitches */
#define DEFAULT_PITCH           0x00
#define FIXED_PITCH             0x01
#define VARIABLE_PITCH          0x02

// END

void GetFontPitch( sal_Int32 nOoxValue, sal_Int16 & nPitch, sal_Int16 & nFamily )
{
    sal_Int32 oFamily = ( nOoxValue & 0xf0 );
    sal_Int32 oPitch = ( nOoxValue & 0x0f );
    switch( oFamily )
    {
    case FF_ROMAN:
        nFamily = FontFamily::ROMAN;
        break;
    case FF_SWISS:
        nFamily = FontFamily::SWISS;
        break;
    case FF_MODERN:
        nFamily = FontFamily::MODERN;
        break;
    case FF_SCRIPT:
        nFamily = FontFamily::SCRIPT;
        break;
    case FF_DECORATIVE:
        nFamily = FontFamily::DECORATIVE;
        break;
    default:
        nFamily = FontFamily::DONTKNOW;
        break;
    }
    switch( oPitch )
    {
    case FIXED_PITCH:
        nPitch = FontPitch::FIXED;
        break;
    case VARIABLE_PITCH:
        nPitch = FontPitch::VARIABLE;
        break;
    case DEFAULT_PITCH:
    default:
        nPitch = FontPitch::DONTKNOW;
        break;
    }
}

/** converts a paragraph align to a ParaAdjust */
sal_Int16 GetParaAdjust( sal_Int32 nAlign )
{
    sal_Int16 nEnum;
    switch( nAlign )
    {
    case XML_ctr:
        nEnum = ParagraphAdjust_CENTER;
        break;
    case XML_just:
    case XML_justLow:
        nEnum = ParagraphAdjust_BLOCK;
        break;
    case XML_r:
        nEnum = ParagraphAdjust_RIGHT;
        break;
    case XML_thaiDist:
    case XML_dist:
        nEnum = ParagraphAdjust_STRETCH;
        break;
    case XML_l:
    default:
        nEnum = ParagraphAdjust_LEFT;
        break;
    }
    return nEnum;
}

TabAlign GetTabAlign( sal_Int32 aToken )
{
    TabAlign nEnum;
    switch( aToken )
    {
    case XML_ctr:
        nEnum = TabAlign_CENTER;
        break;
    case XML_dec:
        nEnum = TabAlign_DECIMAL;
        break;
    case XML_l:
        nEnum = TabAlign_LEFT;
        break;
    case XML_r:
        nEnum = TabAlign_RIGHT;
        break;
    default:
        nEnum = TabAlign_DEFAULT;
        break;
    }
    return nEnum;
}

// --------------------------------------------------------------------

/** converts the attributes from a CT_RelativeRect to an IntegerRectangle2D */
IntegerRectangle2D GetRelativeRect( const Reference< XFastAttributeList >& xAttribs )
{
    IntegerRectangle2D r;

    r.X1 = xAttribs->getOptionalValue( XML_l ).toInt32();
    r.Y1 = xAttribs->getOptionalValue( XML_t ).toInt32();
    r.X2 = xAttribs->getOptionalValue( XML_r ).toInt32();
    r.Y2 = xAttribs->getOptionalValue( XML_b ).toInt32();

    return r;
}

// --------------------------------------------------------------------

/** converts the attributes from an CT_Size2D into an awt Size with 1/100thmm */
Size GetSize2D( const Reference< XFastAttributeList >& xAttribs )
{
    return Size( GetCoordinate( xAttribs->getOptionalValue( XML_cx ) ), GetCoordinate( xAttribs->getOptionalValue( XML_cy ) ) );
}

IndexRange GetIndexRange( const Reference< XFastAttributeList >& xAttributes )
{
    IndexRange range;
    range.start = xAttributes->getOptionalValue( XML_st ).toInt32();
    range.end = xAttributes->getOptionalValue( XML_end ).toInt32();
    return range;
}

} }
<|endoftext|>


<commit_before>/*
 * Instantiator.cc
 *
 * Copyright (C) 2009, 2014, 2015 Linas Vepstas
 *
 * Author: Linas Vepstas <linasvepstas@gmail.com>  January 2009
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/atoms/core/DefineLink.h>
#include <opencog/atoms/core/LambdaLink.h>
#include <opencog/atoms/core/PutLink.h>
#include <opencog/atoms/execution/ExecutionOutputLink.h>
#include <opencog/atoms/execution/EvaluationLink.h>
#include <opencog/atoms/reduct/FoldLink.h>
#include <opencog/query/BindLinkAPI.h>

#include "Instantiator.h"

using namespace opencog;

bool Instantiator::walk_tree(HandleSeq& oset_results, const HandleSeq& expr)
{
	bool changed = false;
	for (const Handle& h : expr)
	{
		Handle hg(walk_tree(h));
		if (hg != h) changed = true;

		// GlobNodes are grounded by a ListLink of everything that
		// the GlobNode matches. Unwrap the list, and insert each
		// of the glob elements in sequence.
		if (GLOB_NODE == h->getType() and hg != h)
		{
			LinkPtr lp(LinkCast(hg));
			OC_ASSERT(nullptr != lp, "Expecting glob list");
			for (const Handle& gloe: lp->getOutgoingSet())
			{
				if (NULL != gloe)
					oset_results.emplace_back(gloe);
			}
		}
		else
		{
			// It could be a NULL handle if it's deleted... Just skip
			// over it. We test the pointer here, not the uuid, since
			// the uuid's are all Handle::UNDEFINED until we put them
			// into the atomspace.
			if (NULL != hg)
				oset_results.emplace_back(hg);
		}
	}
	return changed;
}

Handle Instantiator::walk_tree(const Handle& expr)
{
	Type t = expr->getType();

	// Must not explore the insides of a QuoteLink.
	// XXX TODO: Need to implement UNQUOTE_LINK here...
	if (QUOTE_LINK == t)
		return Handle(expr);

	LinkPtr lexpr(LinkCast(expr));
	if (not lexpr)
	{
		// If we are here, we are a Node.
		if (DEFINED_SCHEMA_NODE == t)
		{
			return walk_tree(DefineLink::get_definition(expr));
		}

		if (VARIABLE_NODE != t and GLOB_NODE != t)
			return Handle(expr);

		// If we are here, we found a variable. Look it up. Return a
		// grounding if it has one, otherwise return the variable
		// itself.
		std::map<Handle,Handle>::const_iterator it = _vmap->find(expr);
		if (_vmap->end() == it) return Handle(expr);

		// Not so fast, pardner. VariableNodes can be grounded by
		// links, and those links may be executable. In that case,
		// we have to execute them.

		// halt infinite regress
		if (_halt)
			return Handle(expr);

		_halt = true;
		Handle hgnd(walk_tree(it->second));
		_halt = false;
		return hgnd;
	}

	// -----------------------------------------------------------
	// If we are here, then we have a link. Walk it. In general,
	// links may contain both bound variables, and also free variables.
	// We must be careful to substitute only for free variables, and
	// never for bound ones.
	//
	// Reduce PutLinks.
	if (PUT_LINK == t)
	{
		PutLinkPtr ppp(PutLinkCast(expr));
		if (nullptr == ppp)
			ppp = createPutLink(expr);

		// Execute the values in the PutLink before ding the beta-reduction.
		// Execute the body only after the beta-reduction has been done.
		Handle pvals = ppp->get_values();
		Handle gargs = walk_tree(pvals);
		if (gargs != pvals)
		{
			HandleSeq groset;
			if (ppp->get_vardecl())
				groset.emplace_back(ppp->get_vardecl());
			groset.emplace_back(ppp->get_body());
			groset.emplace_back(gargs);
			ppp = createPutLink(groset);
		}
		// Step one: beta-reduce.
		Handle red(ppp->reduce());
		// Step two: execute the resulting body.
		Handle rex(walk_tree(red));
		if (nullptr == rex)
			return rex;

		// Step three: XXX this is awkward, but seems to be needed...
		// If the result is evaluatable, then evaluate it. e.g. if the
		// result has a GroundedPredicateNode, we need to run it now.
		// We do, however, ignore the reulsting TV, which is also
		// awkward.  I'm confused about how to handle this best.
		// The behavior tree uses this!
		// Anyway, do_evaluate() will throw if rex is not evaluatable.
		if (SET_LINK == rex->getType())
		{
			LinkPtr slp(LinkCast(rex));
			for (const Handle& plo : slp->getOutgoingSet())
			{
				try {
					EvaluationLink::do_evaluate(_as, plo);
				}
				catch (...) {}
			}
			return rex;
		}
		try {
			EvaluationLink::do_evaluate(_as, rex);
		}
		catch (...) {}
		return rex;
	}

	// ExecutionOutputLinks are not handled by the FunctionLink factory
	// below. This is due to a circular shared-libarary dependency.
	if (EXECUTION_OUTPUT_LINK == t)
	{
		// At this time, the GSN or the DSN is always in position 0
		// of the outgoing set, and the ListLink of arguments is always
		// in position 1.  Someday in the future, there may be a variable
		// declaration; we punt on that.
		Handle sn(lexpr->getOutgoingAtom(0));
		Handle args(lexpr->getOutgoingAtom(1));

		// Perform substitution on the args, only.
		args = walk_tree(args);

		// If its a DSN, obtain the correct body for it.
		if (DEFINED_SCHEMA_NODE == sn->getType())
			sn = DefineLink::get_definition(sn);

		// If its an anonymous function link, execute it here.
		if (LAMBDA_LINK == sn->getType())
		{
			LambdaLinkPtr flp(LambdaLinkCast(sn));
			if (NULL == flp)
				flp = createLambdaLink(*LinkCast(sn));

			// Two-step process. First, plug the arguments into the
			// function; i.e. perform beta-reduction. Second, actually
			// execute the result. We execute by just calling walk_tree
			// again.
			Handle body(flp->get_body());
			Variables vars(flp->get_variables());

			const HandleSeq& oset(LinkCast(args)->getOutgoingSet());
			Handle beta_reduced(vars.substitute_nocheck(body, oset));
			return walk_tree(beta_reduced);
		}

		ExecutionOutputLinkPtr eolp(createExecutionOutputLink(sn, args));
		return eolp->execute(_as);
	}

	// FoldLink's cannot be handled by the factory below, due to
	// ciruclar shared library dependencies. Yuck. Something better
	// than a factory needs to be invented.
	if (classserver().isA(t, FOLD_LINK))
	{
		// At this time, no FoldLink ever has a variable declaration,
		// and the number of arguments is not fixed, i.e. variadic.
		// Perform substitution on all arguments before applying the
		// function itself.
		HandleSeq oset_results;
		walk_tree(oset_results, lexpr->getOutgoingSet());
		Handle hl(FoldLink::factory(t, oset_results));
		FoldLinkPtr flp(FoldLinkCast(hl));
		return flp->execute(_as);
	}

	// Handle DeleteLink's before general FunctionLink's; they
	// work differently.
	if (DELETE_LINK == t)
	{
		HandleSeq oset_results;
		walk_tree(oset_results, lexpr->getOutgoingSet());
		for (const Handle& h: oset_results)
		{
			Type ht = h->getType();
			if (VARIABLE_NODE != ht and GLOB_NODE != ht)
				_as->remove_atom(h, true);
		}
		return Handle::UNDEFINED;
	}

	// Fire any other function links, not handled above.
	if (classserver().isA(t, FUNCTION_LINK))
	{
		// At this time, no FunctionLink that is outsode of an
		// ExecutionOutputLink ever has a variable declaration.
		// Also, the number of arguments is not fixed, i.e. variadic.
		// Perform substitution on all arguments before applying the
		// function itself.
		HandleSeq oset_results;
		walk_tree(oset_results, lexpr->getOutgoingSet());
		Handle hl(FunctionLink::factory(t, oset_results));
		FunctionLinkPtr flp(FunctionLinkCast(hl));
		return flp->execute(_as);
	}

	// If there is a GetLink, we have to perform the get, and replace
	// it with the results of the get. The get is implemented with the
	// PatternLink::satisfy() method.
	if (GET_LINK == t)
	{
		HandleSeq oset_results;
		walk_tree(oset_results, lexpr->getOutgoingSet());
		size_t sz = oset_results.size();
		for (size_t i=0; i< sz; i++)
			oset_results[i] = _as->add_atom(oset_results[i]);

		LinkPtr lp(createLink(GET_LINK, oset_results));

		return satisfying_set(_as, Handle(lp));
	}

	// None of the above. Create a duplicate link, but with an outgoing
	// set where the variables have been substituted by their values.
	HandleSeq oset_results;
	bool changed = walk_tree(oset_results, lexpr->getOutgoingSet());
	if (changed)
		return Handle(createLink(t, oset_results, expr->getTruthValue()));
	return expr;
}

/**
 * instantiate -- create a grounded expression from an ungrounded one.
 *
 * Given a handle to an ungrounded expression, and a set of groundings,
 * this will create a grounded expression.
 *
 * The set of groundings is to be passed in with the map 'vars', which
 * maps variable names to their groundings -- it maps variable names to
 * atoms that already exist in the atomspace.  This method will then go
 * through all of the variables in the expression, and substitute them
 * with their values, creating a new expression. The new expression is
 * added to the atomspace, and its handle is returned.
 */
Handle Instantiator::instantiate(const Handle& expr,
                                 const std::map<Handle, Handle> &vars)
{
	// throw, not assert, because this is a user error ...
	if (nullptr == expr)
		throw InvalidParamException(TRACE_INFO,
			"Asked to ground a null expression");

	_vmap = &vars;

	// The returned handle is not yet in the atomspace. Add it now.
	// We do this here, instead of in walk_tree(), because adding
	// atoms to the atomspace is an expensive process.  We can save
	// some time by doing it just once, right here, in one big batch.
	return _as->add_atom(walk_tree(expr));
}

/* ===================== END OF FILE ===================== */
<commit_msg>Bug fix for previous checkin<commit_after>/*
 * Instantiator.cc
 *
 * Copyright (C) 2009, 2014, 2015 Linas Vepstas
 *
 * Author: Linas Vepstas <linasvepstas@gmail.com>  January 2009
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/atoms/core/DefineLink.h>
#include <opencog/atoms/core/LambdaLink.h>
#include <opencog/atoms/core/PutLink.h>
#include <opencog/atoms/execution/ExecutionOutputLink.h>
#include <opencog/atoms/execution/EvaluationLink.h>
#include <opencog/atoms/reduct/FoldLink.h>
#include <opencog/query/BindLinkAPI.h>

#include "Instantiator.h"

using namespace opencog;

bool Instantiator::walk_tree(HandleSeq& oset_results, const HandleSeq& expr)
{
	bool changed = false;
	for (const Handle& h : expr)
	{
		Handle hg(walk_tree(h));
		if (hg != h) changed = true;

		// GlobNodes are grounded by a ListLink of everything that
		// the GlobNode matches. Unwrap the list, and insert each
		// of the glob elements in sequence.
		if (GLOB_NODE == h->getType() and hg != h)
		{
			LinkPtr lp(LinkCast(hg));
			OC_ASSERT(nullptr != lp, "Expecting glob list");
			for (const Handle& gloe: lp->getOutgoingSet())
			{
				if (NULL != gloe)
					oset_results.emplace_back(gloe);
			}
		}
		else
		{
			// It could be a NULL handle if it's deleted... Just skip
			// over it. We test the pointer here, not the uuid, since
			// the uuid's are all Handle::UNDEFINED until we put them
			// into the atomspace.
			if (NULL != hg)
				oset_results.emplace_back(hg);
		}
	}
	return changed;
}

Handle Instantiator::walk_tree(const Handle& expr)
{
	Type t = expr->getType();

	// Must not explore the insides of a QuoteLink.
	// XXX TODO: Need to implement UNQUOTE_LINK here...
	if (QUOTE_LINK == t)
		return Handle(expr);

	LinkPtr lexpr(LinkCast(expr));
	if (not lexpr)
	{
		// If we are here, we are a Node.
		if (DEFINED_SCHEMA_NODE == t)
		{
			return walk_tree(DefineLink::get_definition(expr));
		}

		if (VARIABLE_NODE != t and GLOB_NODE != t)
			return Handle(expr);

		// If we are here, we found a variable. Look it up. Return a
		// grounding if it has one, otherwise return the variable
		// itself.
		std::map<Handle,Handle>::const_iterator it = _vmap->find(expr);
		if (_vmap->end() == it) return Handle(expr);

		// Not so fast, pardner. VariableNodes can be grounded by
		// links, and those links may be executable. In that case,
		// we have to execute them.

		// halt infinite regress
		if (_halt)
			return Handle(expr);

		_halt = true;
		Handle hgnd(walk_tree(it->second));
		_halt = false;
		return hgnd;
	}

	// -----------------------------------------------------------
	// If we are here, then we have a link. Walk it. In general,
	// links may contain both bound variables, and also free variables.
	// We must be careful to substitute only for free variables, and
	// never for bound ones.
	//
	// Reduce PutLinks.
	if (PUT_LINK == t)
	{
		PutLinkPtr ppp(PutLinkCast(expr));
		if (nullptr == ppp)
			ppp = createPutLink(*lexpr);

		// Execute the values in the PutLink before ding the beta-reduction.
		// Execute the body only after the beta-reduction has been done.
		Handle pvals = ppp->get_values();
		Handle gargs = walk_tree(pvals);
		if (gargs != pvals)
		{
			HandleSeq groset;
			if (ppp->get_vardecl())
				groset.emplace_back(ppp->get_vardecl());
			groset.emplace_back(ppp->get_body());
			groset.emplace_back(gargs);
			ppp = createPutLink(groset);
		}
		// Step one: beta-reduce.
		Handle red(ppp->reduce());
		// Step two: execute the resulting body.
		Handle rex(walk_tree(red));
		if (nullptr == rex)
			return rex;

		// Step three: XXX this is awkward, but seems to be needed...
		// If the result is evaluatable, then evaluate it. e.g. if the
		// result has a GroundedPredicateNode, we need to run it now.
		// We do, however, ignore the reulsting TV, which is also
		// awkward.  I'm confused about how to handle this best.
		// The behavior tree uses this!
		// Anyway, do_evaluate() will throw if rex is not evaluatable.
		if (SET_LINK == rex->getType())
		{
			LinkPtr slp(LinkCast(rex));
			for (const Handle& plo : slp->getOutgoingSet())
			{
				try {
					EvaluationLink::do_evaluate(_as, plo);
				}
				catch (...) {}
			}
			return rex;
		}
		try {
			EvaluationLink::do_evaluate(_as, rex);
		}
		catch (...) {}
		return rex;
	}

	// ExecutionOutputLinks are not handled by the FunctionLink factory
	// below. This is due to a circular shared-libarary dependency.
	if (EXECUTION_OUTPUT_LINK == t)
	{
		// At this time, the GSN or the DSN is always in position 0
		// of the outgoing set, and the ListLink of arguments is always
		// in position 1.  Someday in the future, there may be a variable
		// declaration; we punt on that.
		Handle sn(lexpr->getOutgoingAtom(0));
		Handle args(lexpr->getOutgoingAtom(1));

		// Perform substitution on the args, only.
		args = walk_tree(args);

		// If its a DSN, obtain the correct body for it.
		if (DEFINED_SCHEMA_NODE == sn->getType())
			sn = DefineLink::get_definition(sn);

		// If its an anonymous function link, execute it here.
		if (LAMBDA_LINK == sn->getType())
		{
			LambdaLinkPtr flp(LambdaLinkCast(sn));
			if (NULL == flp)
				flp = createLambdaLink(*LinkCast(sn));

			// Two-step process. First, plug the arguments into the
			// function; i.e. perform beta-reduction. Second, actually
			// execute the result. We execute by just calling walk_tree
			// again.
			Handle body(flp->get_body());
			Variables vars(flp->get_variables());

			const HandleSeq& oset(LinkCast(args)->getOutgoingSet());
			Handle beta_reduced(vars.substitute_nocheck(body, oset));
			return walk_tree(beta_reduced);
		}

		ExecutionOutputLinkPtr eolp(createExecutionOutputLink(sn, args));
		return eolp->execute(_as);
	}

	// FoldLink's cannot be handled by the factory below, due to
	// ciruclar shared library dependencies. Yuck. Something better
	// than a factory needs to be invented.
	if (classserver().isA(t, FOLD_LINK))
	{
		// At this time, no FoldLink ever has a variable declaration,
		// and the number of arguments is not fixed, i.e. variadic.
		// Perform substitution on all arguments before applying the
		// function itself.
		HandleSeq oset_results;
		walk_tree(oset_results, lexpr->getOutgoingSet());
		Handle hl(FoldLink::factory(t, oset_results));
		FoldLinkPtr flp(FoldLinkCast(hl));
		return flp->execute(_as);
	}

	// Handle DeleteLink's before general FunctionLink's; they
	// work differently.
	if (DELETE_LINK == t)
	{
		HandleSeq oset_results;
		walk_tree(oset_results, lexpr->getOutgoingSet());
		for (const Handle& h: oset_results)
		{
			Type ht = h->getType();
			if (VARIABLE_NODE != ht and GLOB_NODE != ht)
				_as->remove_atom(h, true);
		}
		return Handle::UNDEFINED;
	}

	// Fire any other function links, not handled above.
	if (classserver().isA(t, FUNCTION_LINK))
	{
		// At this time, no FunctionLink that is outsode of an
		// ExecutionOutputLink ever has a variable declaration.
		// Also, the number of arguments is not fixed, i.e. variadic.
		// Perform substitution on all arguments before applying the
		// function itself.
		HandleSeq oset_results;
		walk_tree(oset_results, lexpr->getOutgoingSet());
		Handle hl(FunctionLink::factory(t, oset_results));
		FunctionLinkPtr flp(FunctionLinkCast(hl));
		return flp->execute(_as);
	}

	// If there is a GetLink, we have to perform the get, and replace
	// it with the results of the get. The get is implemented with the
	// PatternLink::satisfy() method.
	if (GET_LINK == t)
	{
		HandleSeq oset_results;
		walk_tree(oset_results, lexpr->getOutgoingSet());
		size_t sz = oset_results.size();
		for (size_t i=0; i< sz; i++)
			oset_results[i] = _as->add_atom(oset_results[i]);

		LinkPtr lp(createLink(GET_LINK, oset_results));

		return satisfying_set(_as, Handle(lp));
	}

	// None of the above. Create a duplicate link, but with an outgoing
	// set where the variables have been substituted by their values.
	HandleSeq oset_results;
	bool changed = walk_tree(oset_results, lexpr->getOutgoingSet());
	if (changed)
		return Handle(createLink(t, oset_results, expr->getTruthValue()));
	return expr;
}

/**
 * instantiate -- create a grounded expression from an ungrounded one.
 *
 * Given a handle to an ungrounded expression, and a set of groundings,
 * this will create a grounded expression.
 *
 * The set of groundings is to be passed in with the map 'vars', which
 * maps variable names to their groundings -- it maps variable names to
 * atoms that already exist in the atomspace.  This method will then go
 * through all of the variables in the expression, and substitute them
 * with their values, creating a new expression. The new expression is
 * added to the atomspace, and its handle is returned.
 */
Handle Instantiator::instantiate(const Handle& expr,
                                 const std::map<Handle, Handle> &vars)
{
	// throw, not assert, because this is a user error ...
	if (nullptr == expr)
		throw InvalidParamException(TRACE_INFO,
			"Asked to ground a null expression");

	_vmap = &vars;

	// The returned handle is not yet in the atomspace. Add it now.
	// We do this here, instead of in walk_tree(), because adding
	// atoms to the atomspace is an expensive process.  We can save
	// some time by doing it just once, right here, in one big batch.
	return _as->add_atom(walk_tree(expr));
}

/* ===================== END OF FILE ===================== */
<|endoftext|>


<commit_before>/*
 * opencog/atoms/truthvalue/TTruthValue.cc
 *
 * Written by Anatoly Belikov <abelikov@singularitynet.io>
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/atoms/truthvalue/TTruthValue.h>
#include "SimpleTruthValue.h"

#include <Python.h>

using namespace opencog;

TTruthValue::TTruthValue(PyObject * p):TruthValue(TTRUTH_VALUE), ptr(p), _count(1){
   PyGILState_STATE state = PyGILState_Ensure();
   Py_INCREF(p);
   PyGILState_Release(state);
};

float TTruthValue::getAttr(std::string p_attrname) const{
    PyGILState_STATE state = PyGILState_Ensure();
    PyObject * tensor = (PyObject*)(this->ptr);
    PyObject * const attrname = PyUnicode_FromString(p_attrname.c_str());
    PyObject * res_obj = PyObject_GetAttr(tensor, attrname);
    PyObject * float_obj = nullptr;
    Py_DECREF(attrname);
    bool failed = false;
    double result;
    if (res_obj){
        float_obj = PyObject_CallMethod(res_obj, "__float__", NULL);
        if(float_obj) {
            result  = PyFloat_AsDouble(float_obj);
        }
    } else {
        failed = true;
    }
    if(res_obj) Py_DECREF(res_obj);
    if(float_obj) Py_DECREF(float_obj);
    PyGILState_Release(state);
    if(failed)
        throw RuntimeException(TRACE_INFO, "failed to get element of tensor");
    return result;
}

strength_t TTruthValue::get_mean()  const {
    return this->getAttr("mean");
}

confidence_t TTruthValue::get_confidence()  const {
    return this->getAttr("confidence");
}

count_t TTruthValue::get_count()  const {
    return this->_count;
}

TruthValuePtr TTruthValue::clone() const {
    PyObject * tensor = (PyObject*)(this->ptr);
    PyObject * res_obj = PyObject_CallMethod(tensor, "clone", NULL);
    if(res_obj == nullptr){
         throw RuntimeException(TRACE_INFO, "failed to clone object");
    }
    return createTTruthValue(res_obj);
}

bool TTruthValue::operator==(const Value& other) const {
     return this == &other;
}

TruthValuePtr TTruthValue::merge(const TruthValuePtr& other,
                                      const MergeCtrl& mc) const
{
            throw RuntimeException(TRACE_INFO,
                                   "merge is not implemented");
}

TTruthValue::~TTruthValue(){
    PyGILState_STATE state = PyGILState_Ensure();
    Py_DECREF(this->ptr);
    PyGILState_Release(state);
}

void * TTruthValue::getPtr(){
    return this->ptr;
}

<commit_msg>acquire gil in TTruthValue::clone<commit_after>/*
 * opencog/atoms/truthvalue/TTruthValue.cc
 *
 * Written by Anatoly Belikov <abelikov@singularitynet.io>
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/atoms/truthvalue/TTruthValue.h>
#include "SimpleTruthValue.h"

#include <Python.h>

using namespace opencog;

TTruthValue::TTruthValue(PyObject * p):TruthValue(TTRUTH_VALUE), ptr(p), _count(1){
   PyGILState_STATE state = PyGILState_Ensure();
   Py_INCREF(p);
   PyGILState_Release(state);
};

float TTruthValue::getAttr(std::string p_attrname) const{
    PyGILState_STATE state = PyGILState_Ensure();
    PyObject * tensor = (PyObject*)(this->ptr);
    PyObject * const attrname = PyUnicode_FromString(p_attrname.c_str());
    PyObject * res_obj = PyObject_GetAttr(tensor, attrname);
    PyObject * float_obj = nullptr;
    Py_DECREF(attrname);
    bool failed = false;
    double result;
    if (res_obj){
        float_obj = PyObject_CallMethod(res_obj, "__float__", NULL);
        if(float_obj) {
            result  = PyFloat_AsDouble(float_obj);
        }
    } else {
        failed = true;
    }
    if(res_obj) Py_DECREF(res_obj);
    if(float_obj) Py_DECREF(float_obj);
    PyGILState_Release(state);
    if(failed)
        throw RuntimeException(TRACE_INFO, "failed to get element of tensor");
    return result;
}

strength_t TTruthValue::get_mean()  const {
    return this->getAttr("mean");
}

confidence_t TTruthValue::get_confidence()  const {
    return this->getAttr("confidence");
}

count_t TTruthValue::get_count()  const {
    return this->_count;
}

TruthValuePtr TTruthValue::clone() const {
    PyObject * tensor = (PyObject*)(this->ptr);
    PyGILState_STATE state = PyGILState_Ensure();
    PyObject * res_obj = PyObject_CallMethod(tensor, "clone", NULL);
    PyGILState_Release(state);
    if(res_obj == nullptr){
         throw RuntimeException(TRACE_INFO, "failed to clone object");
    }
    return createTTruthValue(res_obj);
}

bool TTruthValue::operator==(const Value& other) const {
     return this == &other;
}

TruthValuePtr TTruthValue::merge(const TruthValuePtr& other,
                                      const MergeCtrl& mc) const
{
            throw RuntimeException(TRACE_INFO,
                                   "merge is not implemented");
}

TTruthValue::~TTruthValue(){
    PyGILState_STATE state = PyGILState_Ensure();
    Py_DECREF(this->ptr);
    PyGILState_Release(state);
}

void * TTruthValue::getPtr(){
    return this->ptr;
}

<|endoftext|>


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

    types.hpp - support file for writing LV2 plugins in C++

    Copyright (C) 2006-2008 Lars Luthman <lars.luthman@gmail.com>

    The first version of the URIMap class was written by Dave Robillard.
    It has since been modified.

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307  USA

****************************************************************************/
/** @headerfile lvtk/types.hpp */

#ifndef LVTK_LV2_TYPES_HPP
#define LVTK_LV2_TYPES_HPP

#include <map>
#include <string>

#include <lvtk/feature.hpp>

#include "debug.hpp"

#include <lv2/lv2plug.in/ns/lv2core/lv2.h>
#include <lv2/lv2plug.in/ns/extensions/ui/ui.h>

/** @namespace lvtk */
namespace lvtk {
   /** Convenience typedefs */
   typedef LV2_Handle Handle;

   namespace ui {
       typedef LV2UI_Handle Handle;
   }
}

namespace lvtk {

   /** @internal This class is used by the end class */
   struct empty {};

   /** @internal
      This class is used to terminate the recursive inheritance trees
      created by MixinTree. */
   struct end {
    typedef empty C;
   };

  /** @internal
      This template class creates an inheritance tree of extension templates
      from a parameter list. It is inherited by the Plugin class to make
      it possible to add overridable extension functions to the class.
      The first template parameter will be used as the first template
      parameter of @c E1, and also be passed as the first parameter of the
      next level of the inheritance tree. Each @c bool parameter will be used
      as the second parameter to the template directly preceding it. */
  template <class A,
	    class E1 = end,
	    class E2 = end,
	    class E3 = end,
	    class E4 = end,
	    class E5 = end,
	    class E6 = end,
	    class E7 = end,
	    class E8 = end,
	    class E9 = end>
  struct MixinTree
    : E1::template I<A>, MixinTree<A, E2, E3, E4, E5, E6, E7, E8, E9>
  {

    typedef MixinTree<A, E2, E3, E4, E5, E6, E7, E8, E9> Parent;

    /** @internal
	Add feature handlers to @c hmap for the feature URIs. */
    static void
    map_feature_handlers(feature_handler_map& hmap)
    {
      E1::template I<A>::map_feature_handlers(hmap);
      Parent::map_feature_handlers(hmap);
    }

    /** Check if the features are OK with the plugin initialisation. */
    bool
    check_ok()
    {
      return E1::template I<A>::check_ok() && Parent::check_ok();
    }

    /** Return any extension data. */
    static const void*
    extension_data(const char* uri)
    {
		const void* result = E1::template I<A>::extension_data (uri);
		if (result)
		{
			return result;
		}
		return Parent::extension_data (uri);
    }

  };

  /** @internal
      This is a specialization of the inheritance tree template that terminates
      the recursion. */
  template <class A>
  struct MixinTree<A, end, end, end, end, end, end, end, end, end> {
    static void map_feature_handlers(feature_handler_map& hmap) { }
    bool check_ok() const { return true; }
    static const void* extension_data(const char* uri) { return 0; }
  };

  /** @internal
      Base class for extensions. extension mixin classes don't have to
      inherit from this class, but it's convenient.
  */
  template <bool Required>
  struct Extension {

    /** @internal
     */
    Extension() : m_ok(!Required) { }

    /** @internal
	Default implementation does nothing - no handlers added.
    */
    static void
    map_feature_handlers(feature_handler_map& hmap) { }

    /** @internal
	Return @c true if the plugin instance is OK, @c false if it isn't.
    */
    bool check_ok() { return m_ok; }

    /** @internal
	Return a data pointer corresponding to the URI if this extension
	has one.
    */
    static const void*
    extension_data(const char* uri) { return 0; }

  protected:

    bool m_ok;

  };

  template <bool Required = true>
  struct Behavior : Extension<Required>
  {

  };

}

#endif
<commit_msg>Housekeeping, fixing indendation errors.<commit_after>/****************************************************************************

    types.hpp - support file for writing LV2 plugins in C++

    Copyright (C) 2006-2008 Lars Luthman <lars.luthman@gmail.com>

    The first version of the URIMap class was written by Dave Robillard.
    It has since been modified.

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307  USA

 ****************************************************************************/
/** @headerfile lvtk/types.hpp */

#ifndef LVTK_LV2_TYPES_HPP
#define LVTK_LV2_TYPES_HPP

#include <map>
#include <string>

#include <lvtk/feature.hpp>

#include "debug.hpp"

#include <lv2/lv2plug.in/ns/lv2core/lv2.h>
#include <lv2/lv2plug.in/ns/extensions/ui/ui.h>

/** @namespace lvtk */
namespace lvtk {
    /** Convenience typedefs */
    typedef LV2_Handle Handle;

    namespace ui {
        typedef LV2UI_Handle Handle;
    }
}

namespace lvtk {

    /** @internal This class is used by the end class */
    struct empty {};

    /** @internal
      This class is used to terminate the recursive inheritance trees
      created by MixinTree. */
    struct end {
        typedef empty C;
    };

    /** @internal
      This template class creates an inheritance tree of extension templates
      from a parameter list. It is inherited by the Plugin class to make
      it possible to add overridable extension functions to the class.
      The first template parameter will be used as the first template
      parameter of @c E1, and also be passed as the first parameter of the
      next level of the inheritance tree. Each @c bool parameter will be used
      as the second parameter to the template directly preceding it. */
    template <class A,
    class E1 = end,
    class E2 = end,
    class E3 = end,
    class E4 = end,
    class E5 = end,
    class E6 = end,
    class E7 = end,
    class E8 = end,
    class E9 = end>
    struct MixinTree
    : E1::template I<A>, MixinTree<A, E2, E3, E4, E5, E6, E7, E8, E9>
    {

        typedef MixinTree<A, E2, E3, E4, E5, E6, E7, E8, E9> Parent;

        /** @internal
	Add feature handlers to @c hmap for the feature URIs. */
        static void
        map_feature_handlers(feature_handler_map& hmap)
        {
            E1::template I<A>::map_feature_handlers(hmap);
            Parent::map_feature_handlers(hmap);
        }

        /** Check if the features are OK with the plugin initialisation. */
        bool
        check_ok()
        {
            return E1::template I<A>::check_ok() && Parent::check_ok();
        }

        /** Return any extension data. */
        static const void*
        extension_data(const char* uri)
        {
            const void* result = E1::template I<A>::extension_data (uri);
            if (result)
            {
                return result;
            }
            return Parent::extension_data (uri);
        }

    };

    /** @internal
      This is a specialization of the inheritance tree template that terminates
      the recursion. */
    template <class A>
    struct MixinTree<A, end, end, end, end, end, end, end, end, end> {
        static void map_feature_handlers(feature_handler_map& hmap) { }
        bool check_ok() const { return true; }
        static const void* extension_data(const char* uri) { return 0; }
    };

    /** @internal
      Base class for extensions. extension mixin classes don't have to
      inherit from this class, but it's convenient.
     */
    template <bool Required>
    struct Extension {

        /** @internal
         */
        Extension() : m_ok(!Required) { }

        /** @internal
	Default implementation does nothing - no handlers added.
         */
        static void
        map_feature_handlers(feature_handler_map& hmap) { }

        /** @internal
	Return @c true if the plugin instance is OK, @c false if it isn't.
         */
        bool check_ok() { return m_ok; }

        /** @internal
	Return a data pointer corresponding to the URI if this extension
	has one.
         */
        static const void*
        extension_data(const char* uri) { return 0; }

    protected:

        bool m_ok;

    };

    template <bool Required = true>
    struct Behavior : Extension<Required>
    {

    };

}

#endif
<|endoftext|>