<commit_before>#include <limits>
#include <algorithm>
#include <array>
#include <iomanip>
#include <curl/curl.h>
#include <memory>
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include <sys/stat.h>
#include <cerrno>
#include <cstring>
#include <system_error>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>

const std::string listing("http://nwn.efupw.com/rootdir/index.dat");
const std::string patch_dir("http://nwn.efupw.com/rootdir/patch/");
const std::string update_check("");

const std::string file_checksum(const std::string &path);

size_t writefunction(const char *ptr, size_t size, size_t nmemb, void *userdata)
{
    std::string *s = static_cast<std::string *>(userdata);
    s->append(ptr, size * nmemb);
    return size * nmemb;
}

std::vector<std::string> &split(const std::string &s, char delim,
        std::vector<std::string> &elems)
{
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim))
    {
        elems.push_back(item);
    }
    return elems;
}

std::vector<std::string> split(const std::string &s, char delim)
{
    std::vector<std::string> elems;
    return split(s, delim, elems);
}

class Target
{
    public:
        enum class Status {
            Nonexistent,
            Outdated,
            Current
        };
        explicit Target(const std::string &name, const std::string &checksum):
            m_name(name.find_first_of('/') == std::string::npos ? name :
                    name, name.find_first_of('/') + 1, name.size() - 1),
            m_checksum(checksum)
            {}
        std::string name() const { return m_name; }
        const std::string checksum() const { return m_checksum; }

        void fetch()
        {
            std::cout << "Statting target " << name() << "...";
            std::string path;
            std::fstream fs(name(), std::ios_base::in);
            if (!fs.good())
            {
                fs.close();
                std::cout << " doesn't exist, creating new." << std::endl;
                auto elems = split(name(), '/');
                for (size_t i = 0, k = elems.size(); i < k; ++i)
                {
                    const std::string &s(elems[i]);
                    if (s.size() && s != ".")
                    {
                        path.append((i > 0 ? "/" : "") + s);
                        // i indicates a directory.
                        if (i < k - 1)
                        {
                            auto status = mkdir(path.c_str(), S_IRWXU);
                            if (status == -1)
                            {
                                std::error_code err(errno, std::generic_category());
                                if (err != std::errc::file_exists)
                                {
                                    std::cout << "error making dir: "
                                        << path << ": "
                                        << err.message() << std::endl;
                                }
                            }
                        }
                    }
                }
                fs.open(path, std::ios_base::out);
                if (!fs.good())
                {
                    fs.close();
                    std::cout << "Failed to create file: " << path << std::endl;
                }
                else
                {
                    fs.close();
                    do_fetch();
                    return;
                }
            }
            if (fs.good())
            {
                fs.close();
                if (status() == Status::Current)
                {
                    std::cout << " already up to date." << std::endl;
                }
                else
                {
                    std::cout << " outdated, downloading new." << std::endl;
                    do_fetch();
                }
            }
        }
        Status status()
        {
            std::ifstream is(name());
            if (!is.good())
            {
                return Status::Nonexistent;
            }
            is.close();
            auto calcsum(file_checksum(name()));
            if (calcsum == checksum())
            {
                return Status::Current;
            }
            else
            {
                return Status::Outdated;
            }
        }

    private:
        void do_fetch()
        {
            std::string s;
            std::shared_ptr<CURL *> phandle =
                std::make_shared<CURL *>(curl_easy_init());
            std::string url(patch_dir + name());
            curl_easy_setopt(*phandle, CURLOPT_URL, url.c_str());
            curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
            curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &s);
            //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
            curl_easy_perform(*phandle);
            curl_easy_cleanup(*phandle);
            phandle.reset();
            std::ofstream ofs(name());
            if (ofs.good())
            {
                ofs << s;
                ofs.close();
                std::cout << "Finished downloading " << name() << std::endl;
            }
            else
            {
                std::cout << "Couldn't write to " << name() << std::endl;
            }
        }

        std::string m_name;
        std::string m_checksum;
};

std::ostream& operator<<(std::ostream &os, const Target &t)
{
    return os << "name: " << t.name() << ", checksum: " << t.checksum();
}

class CurlGlobalInit
{
    public:
        CurlGlobalInit()
        {
            curl_global_init(CURL_GLOBAL_ALL);
        }

        ~CurlGlobalInit()
        {
            curl_global_cleanup();
        }
};

const std::string file_checksum(const std::string &path)
{
#ifdef md_md5
    auto md = EVP_md5();
    const int md_len = MD5_DIGEST_LENGTH;
#else
    auto md = EVP_sha1();
    const int md_len = SHA_DIGEST_LENGTH;
#endif
    std::array<unsigned char, md_len> result;
    EVP_MD_CTX *mdctx = nullptr;
    std::ifstream is(path, std::ifstream::binary);
    if (!is.good())
    {
        std::cout << "Couldn't open file " << path
           << " for checksumming." << std::endl;
        return std::string();
    }

    const int length = 8192;
    std::array<unsigned char, length> buffer;
    auto buf = reinterpret_cast<char *>(buffer.data());
    mdctx = EVP_MD_CTX_create();
    int status = EVP_DigestInit_ex(mdctx, md, nullptr);
    while (status && is)
    {
        is.read(buf, length);
        status = EVP_DigestUpdate(mdctx, buffer.data(), is.gcount());
    }
    status = EVP_DigestFinal_ex(mdctx, result.data(), nullptr);
    EVP_MD_CTX_destroy(mdctx);
    std::stringstream calcsum;
    calcsum << std::setfill('0');

    for (unsigned char c : result)
    {
        calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
    }
    /*
    std::for_each(std::begin(result), std::end(result),
            [&calcsum](unsigned char c)
            {
            calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
            });
            */

    return calcsum.str();
}

struct Options
{
    bool checksum(const std::string &val)
    {
        return val == "checksum";
    }
};

bool confirm()
{
    char c;
    do
    {
        std::cin >> c;
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        c = tolower(c);
    } while (c != 'y' && c != 'n');
    return c == 'y';
}

int main(int argc, char *argv[])
{
    CurlGlobalInit curl_global;

    const std::string update_check("https://raw.github.com/commonquail/efulauncher/updatecheck/versioncheck");
    std::string fetch;
    std::shared_ptr<CURL *> phandle = std::make_shared<CURL *>(curl_easy_init());
    curl_easy_setopt(*phandle, CURLOPT_URL, update_check.c_str());
    curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
    curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &fetch);
    //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
    curl_easy_perform(*phandle);
    curl_easy_cleanup(*phandle);

    Options opts;
    std::vector<std::string> lines(split(fetch, '\n'));
    fetch.clear();
    for (auto beg = std::begin(lines), end = std::end(lines);
            beg != end; ++beg)
    {
        auto keyvals(split(*beg, '='));
        if (opts.checksum(keyvals[0]))
        {
            const std::string checksum_test(keyvals[keyvals.size() - 1]);
            if (checksum_test != file_checksum(argv[0]))
            {
                std::cout << "A new version of the launcher is available."\
                    " Would you like to download it (y/n)?" << std::endl;
                bool download(confirm());
                if (!download)
                {
                    std::cout << "It is strongly recommended to always use the latest launcher."\
                        " Would you like to download it (y/n)?" << std::endl;
                    download = confirm();
                }
                if (download)
                {
                    // Download.
                    std::cout << "Downloading new launcher..." << std::endl;
                    std::cout << "Done." << std::endl;
                }
            }
        }
    }

    phandle = std::make_shared<CURL *>(curl_easy_init());
    curl_easy_setopt(*phandle, CURLOPT_URL, listing.c_str());
    curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
    curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &fetch);
    //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
    curl_easy_perform(*phandle);
    curl_easy_cleanup(*phandle);
    phandle.reset();

    lines = split(fetch, '\n');
    std::vector<Target> new_targets, old_targets;
    for (auto beg = std::begin(lines), end = std::end(lines);
            beg != end; ++beg)
    {
        auto data(split(*beg, '@'));
        Target t(data[0], data[data.size() - 1]);
        auto status = t.status();
        if (status == Target::Status::Nonexistent)
        {
            new_targets.push_back(std::move(t));
        }
        else if (status == Target::Status::Outdated)
        {
            old_targets.push_back(std::move(t));
        }
    }
    if (new_targets.size())
    {
        std::cout << "New targets: " << new_targets.size() << std::endl;
        for (auto &t : new_targets)
        {
            std::cout << "- " << t.name() << std::endl;
        }
    }
    else
    {
        std::cout << "No new targets." << std::endl;
    }

    if (old_targets.size())
    {
        std::cout << "Outdated targets: " << old_targets.size() << std::endl;
        for (auto &t : old_targets)
        {
            std::cout << "- " << t.name() << std::endl;
        }
    }
    else
    {
        std::cout << "No targets out of date." << std::endl;
    }

#ifndef DEBUG
    for (auto &t : new_targets)
    {
        t.fetch();
    }
    for (auto &t : old_targets)
    {
        t.fetch();
    }
#endif

    return 0;
}
<commit_msg>Make class Options a namespace instead.<commit_after>#include <limits>
#include <algorithm>
#include <array>
#include <iomanip>
#include <curl/curl.h>
#include <memory>
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include <sys/stat.h>
#include <cerrno>
#include <cstring>
#include <system_error>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>

const std::string listing("http://nwn.efupw.com/rootdir/index.dat");
const std::string patch_dir("http://nwn.efupw.com/rootdir/patch/");
const std::string update_check("");

const std::string file_checksum(const std::string &path);

size_t writefunction(const char *ptr, size_t size, size_t nmemb, void *userdata)
{
    std::string *s = static_cast<std::string *>(userdata);
    s->append(ptr, size * nmemb);
    return size * nmemb;
}

std::vector<std::string> &split(const std::string &s, char delim,
        std::vector<std::string> &elems)
{
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim))
    {
        elems.push_back(item);
    }
    return elems;
}

std::vector<std::string> split(const std::string &s, char delim)
{
    std::vector<std::string> elems;
    return split(s, delim, elems);
}

class Target
{
    public:
        enum class Status {
            Nonexistent,
            Outdated,
            Current
        };
        explicit Target(const std::string &name, const std::string &checksum):
            m_name(name.find_first_of('/') == std::string::npos ? name :
                    name, name.find_first_of('/') + 1, name.size() - 1),
            m_checksum(checksum)
            {}
        std::string name() const { return m_name; }
        const std::string checksum() const { return m_checksum; }

        void fetch()
        {
            std::cout << "Statting target " << name() << "...";
            std::string path;
            std::fstream fs(name(), std::ios_base::in);
            if (!fs.good())
            {
                fs.close();
                std::cout << " doesn't exist, creating new." << std::endl;
                auto elems = split(name(), '/');
                for (size_t i = 0, k = elems.size(); i < k; ++i)
                {
                    const std::string &s(elems[i]);
                    if (s.size() && s != ".")
                    {
                        path.append((i > 0 ? "/" : "") + s);
                        // i indicates a directory.
                        if (i < k - 1)
                        {
                            auto status = mkdir(path.c_str(), S_IRWXU);
                            if (status == -1)
                            {
                                std::error_code err(errno, std::generic_category());
                                if (err != std::errc::file_exists)
                                {
                                    std::cout << "error making dir: "
                                        << path << ": "
                                        << err.message() << std::endl;
                                }
                            }
                        }
                    }
                }
                fs.open(path, std::ios_base::out);
                if (!fs.good())
                {
                    fs.close();
                    std::cout << "Failed to create file: " << path << std::endl;
                }
                else
                {
                    fs.close();
                    do_fetch();
                    return;
                }
            }
            if (fs.good())
            {
                fs.close();
                if (status() == Status::Current)
                {
                    std::cout << " already up to date." << std::endl;
                }
                else
                {
                    std::cout << " outdated, downloading new." << std::endl;
                    do_fetch();
                }
            }
        }
        Status status()
        {
            std::ifstream is(name());
            if (!is.good())
            {
                return Status::Nonexistent;
            }
            is.close();
            auto calcsum(file_checksum(name()));
            if (calcsum == checksum())
            {
                return Status::Current;
            }
            else
            {
                return Status::Outdated;
            }
        }

    private:
        void do_fetch()
        {
            std::string s;
            std::shared_ptr<CURL *> phandle =
                std::make_shared<CURL *>(curl_easy_init());
            std::string url(patch_dir + name());
            curl_easy_setopt(*phandle, CURLOPT_URL, url.c_str());
            curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
            curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &s);
            //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
            curl_easy_perform(*phandle);
            curl_easy_cleanup(*phandle);
            phandle.reset();
            std::ofstream ofs(name());
            if (ofs.good())
            {
                ofs << s;
                ofs.close();
                std::cout << "Finished downloading " << name() << std::endl;
            }
            else
            {
                std::cout << "Couldn't write to " << name() << std::endl;
            }
        }

        std::string m_name;
        std::string m_checksum;
};

std::ostream& operator<<(std::ostream &os, const Target &t)
{
    return os << "name: " << t.name() << ", checksum: " << t.checksum();
}

class CurlGlobalInit
{
    public:
        CurlGlobalInit()
        {
            curl_global_init(CURL_GLOBAL_ALL);
        }

        ~CurlGlobalInit()
        {
            curl_global_cleanup();
        }
};

const std::string file_checksum(const std::string &path)
{
#ifdef md_md5
    auto md = EVP_md5();
    const int md_len = MD5_DIGEST_LENGTH;
#else
    auto md = EVP_sha1();
    const int md_len = SHA_DIGEST_LENGTH;
#endif
    std::array<unsigned char, md_len> result;
    EVP_MD_CTX *mdctx = nullptr;
    std::ifstream is(path, std::ifstream::binary);
    if (!is.good())
    {
        std::cout << "Couldn't open file " << path
           << " for checksumming." << std::endl;
        return std::string();
    }

    const int length = 8192;
    std::array<unsigned char, length> buffer;
    auto buf = reinterpret_cast<char *>(buffer.data());
    mdctx = EVP_MD_CTX_create();
    int status = EVP_DigestInit_ex(mdctx, md, nullptr);
    while (status && is)
    {
        is.read(buf, length);
        status = EVP_DigestUpdate(mdctx, buffer.data(), is.gcount());
    }
    status = EVP_DigestFinal_ex(mdctx, result.data(), nullptr);
    EVP_MD_CTX_destroy(mdctx);
    std::stringstream calcsum;
    calcsum << std::setfill('0');

    for (unsigned char c : result)
    {
        calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
    }
    /*
    std::for_each(std::begin(result), std::end(result),
            [&calcsum](unsigned char c)
            {
            calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
            });
            */

    return calcsum.str();
}

namespace Options
{
    bool checksum(const std::string &val)
    {
        return val == "checksum";
    }
};

bool confirm()
{
    char c;
    do
    {
        std::cin >> c;
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        c = tolower(c);
    } while (c != 'y' && c != 'n');
    return c == 'y';
}

int main(int argc, char *argv[])
{
    CurlGlobalInit curl_global;

    const std::string update_check("https://raw.github.com/commonquail/efulauncher/updatecheck/versioncheck");
    std::string fetch;
    std::shared_ptr<CURL *> phandle = std::make_shared<CURL *>(curl_easy_init());
    curl_easy_setopt(*phandle, CURLOPT_URL, update_check.c_str());
    curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
    curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &fetch);
    //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
    curl_easy_perform(*phandle);
    curl_easy_cleanup(*phandle);

    std::vector<std::string> lines(split(fetch, '\n'));
    fetch.clear();
    for (auto beg = std::begin(lines), end = std::end(lines);
            beg != end; ++beg)
    {
        auto keyvals(split(*beg, '='));
        if (Options::checksum(keyvals[0]))
        {
            const std::string checksum_test(keyvals[keyvals.size() - 1]);
            if (checksum_test != file_checksum(argv[0]))
            {
                std::cout << "A new version of the launcher is available."\
                    " Would you like to download it (y/n)?" << std::endl;
                bool download(confirm());
                if (!download)
                {
                    std::cout << "It is strongly recommended to always use the latest launcher."\
                        " Would you like to download it (y/n)?" << std::endl;
                    download = confirm();
                }
                if (download)
                {
                    // Download.
                    std::cout << "Downloading new launcher..." << std::endl;
                    std::cout << "Done." << std::endl;
                }
            }
        }
    }

    phandle = std::make_shared<CURL *>(curl_easy_init());
    curl_easy_setopt(*phandle, CURLOPT_URL, listing.c_str());
    curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
    curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &fetch);
    //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
    curl_easy_perform(*phandle);
    curl_easy_cleanup(*phandle);
    phandle.reset();

    lines = split(fetch, '\n');
    std::vector<Target> new_targets, old_targets;
    for (auto beg = std::begin(lines), end = std::end(lines);
            beg != end; ++beg)
    {
        auto data(split(*beg, '@'));
        Target t(data[0], data[data.size() - 1]);
        auto status = t.status();
        if (status == Target::Status::Nonexistent)
        {
            new_targets.push_back(std::move(t));
        }
        else if (status == Target::Status::Outdated)
        {
            old_targets.push_back(std::move(t));
        }
    }
    if (new_targets.size())
    {
        std::cout << "New targets: " << new_targets.size() << std::endl;
        for (auto &t : new_targets)
        {
            std::cout << "- " << t.name() << std::endl;
        }
    }
    else
    {
        std::cout << "No new targets." << std::endl;
    }

    if (old_targets.size())
    {
        std::cout << "Outdated targets: " << old_targets.size() << std::endl;
        for (auto &t : old_targets)
        {
            std::cout << "- " << t.name() << std::endl;
        }
    }
    else
    {
        std::cout << "No targets out of date." << std::endl;
    }

#ifndef DEBUG
    for (auto &t : new_targets)
    {
        t.fetch();
    }
    for (auto &t : old_targets)
    {
        t.fetch();
    }
#endif

    return 0;
}
<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/CopasiSE/CopasiSE.cpp,v $
   $Revision: 1.18 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/08/08 17:28:04 $
   End CVS Header */

// Main
//
// (C) Stefan Hoops 2002
//

#include <stdlib.h>
#include <sstream>
#include <string>
#include <iostream>

#define COPASI_MAIN
#define COPASI_TRACE_CONSTRUCTION

#include "copasi.h"
#include "CopasiDataModel/CCopasiDataModel.h"
#include "utilities/CCopasiMessage.h"
#include "utilities/CCopasiException.h"
#include "utilities/CCopasiTask.h"
#include "utilities/CCopasiProblem.h"
#include "commandline/COptionParser.h"
#include "commandline/COptions.h"
#include "function/CFunctionDB.h"
#include "function/CEvaluationTree.h"

#include "utilities/CopasiTime.h"
#include "randomGenerator/CRandom.h"
#include "report/CKeyFactory.h"

int main(int argc, char *argv[])
{
  try
    {
      // Parse the commandline options
      COptions::init(argc, argv);
    }

  catch (copasi::autoexcept &e)
    {
      switch (e.get_autothrow_id())
        {
        case copasi::autothrow_help:
          std::cout << "Usage: " << argv[0] << " [options]\n";
          std::cout << e.what();
        }

      return 1;
    }

  catch (copasi::option_error &e)
    {
      std::cerr << argv[0] << ": " << e.what() << "\n";
      std::cerr << e.get_help_comment() << std::endl;

      return 1;
    }

  try
    {
      // Create the root container.
      CCopasiContainer::init();

      // Create the global data model.
      CCopasiDataModel::Global = new CCopasiDataModel;

#ifdef XXXX
      CCallParameters<C_FLOAT64> Variables(20);
      unsigned C_INT32 j, i, imax = Variables.size();
      CRandom * pRandom = CRandom::createGenerator();

      for (i = 0; i < imax; i++)
        {
          C_FLOAT64 * pValue = new C_FLOAT64;
          *pValue = 100.0 * pRandom->getRandomOO();
          Variables[i].value = pValue;
        }

      CCopasiTimer * pCPU =
        const_cast<CCopasiTimer *>(static_cast<const CCopasiTimer *>(CCopasiContainer::Root->getObject((std::string)"CN=Root,Timer=CPU Time")));
      CCopasiTimer * pWall =
        const_cast<CCopasiTimer *>(static_cast<const CCopasiTimer *>(CCopasiContainer::Root->getObject((std::string)"CN=Root,Timer=Wall Clock Time")));

      CCopasiVectorN< CEvaluationTree > & Functions =
        CCopasiDataModel::Global->getFunctionList()->loadedFunctions();
      CFunction * pFunction;

      for (i = 0, imax = Functions.size(); i < imax; i++)
        {
          pFunction = dynamic_cast<CFunction *>(Functions[i]);
          if (pFunction->getType() != CEvaluationTree::MassAction)
            for (j = 0; j < 100000; j++)
              pFunction->calcValue(Variables);
        }

      pCPU->actualize();
      pWall->actualize();

      std::cout << "CPU time:  ";
      pCPU->print(&std::cout);
      std::cout << std::endl;

      std::cout << "Wall time: ";
      pWall->print(&std::cout);
      std::cout << std::endl;
#endif // XXXX

#ifdef XXXX
      CEvaluationTree Expression;
      Expression.setInfix("5**-sin(x)");
      Expression.setInfix("a*5.0/-b");
      Expression.setInfix("EXPONENTIALE+b*c");
      Expression.setInfix("4.0*\"PI+b");
      Expression.setInfix("2*(3+b)");
#endif

      const COptions::nonOptionType & Files = COptions::getNonOptions();

      if (!COptions::compareValue("ImportSBML", std::string("")))
        {
          // Import the SBML File
          std::string ImportSBML;
          COptions::getValue("ImportSBML", ImportSBML);
          CCopasiDataModel::Global->importSBML(ImportSBML);

          // Save the COPASI File, which is the only thing to do.
          std::string Save;
          COptions::getValue("Save", Save);
          CCopasiDataModel::Global->saveModel(Save);
        }

      COptions::nonOptionType::const_iterator it = Files.begin();
      COptions::nonOptionType::const_iterator end = Files.end();

      for (; it != end; ++it)
        {
          CCopasiDataModel::Global->loadModel(*it);

          // Check whether exporting to SBML is requested.
          if (!COptions::compareValue("ExportSBML", std::string("")))
            {
              // Export the SBML File
              std::string ExportSBML;
              COptions::getValue("ExportSBML", ExportSBML);
              CCopasiDataModel::Global->exportSBML(ExportSBML);

              // Since only one export file name can be specified we
              // stop execution.
              return 0;
            }

          CCopasiVectorN< CCopasiTask > & TaskList = * CCopasiDataModel::Global->getTaskList();
          unsigned C_INT32 i, imax = TaskList.size();

          for (i = 0; i < imax; i++)
            if (TaskList[i]->isScheduled())
              {
                TaskList[i]->getProblem()->setModel(CCopasiDataModel::Global->getModel());

                TaskList[i]->initialize();
                TaskList[i]->process();
                TaskList[i]->restore();
              }

          // Check whether a file for saving the resulting model is given
          if (!COptions::compareValue("Save", std::string("")))
            {
              std::string Save;
              COptions::getValue("Save", Save);
              CCopasiDataModel::Global->saveModel(Save);

              // Since only one save file name can be specified we
              // stop execution.
              return 0;
            }

          //      CCopasiDataModel::Global->saveModel("");
        }

      //#endif // XXXX
    }

  catch (CCopasiException Exception)
    {
      std::cout << Exception.getMessage().getText() << std::endl;
    }

  pdelete(CCopasiDataModel::Global);
  pdelete(CCopasiContainer::Root);

  //std::cout << "Leaving main program." << std::endl;
  return 0;
}
<commit_msg>Added missing includes.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/CopasiSE/CopasiSE.cpp,v $
   $Revision: 1.19 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/08/08 18:03:10 $
   End CVS Header */

// Main
//
// (C) Stefan Hoops 2002
//

#include <stdlib.h>
#include <sstream>
#include <string>
#include <iostream>

#define COPASI_MAIN
#define COPASI_TRACE_CONSTRUCTION

#include "copasi.h"
#include "CopasiDataModel/CCopasiDataModel.h"
#include "utilities/CCopasiMessage.h"
#include "utilities/CCopasiException.h"
#include "utilities/CCopasiTask.h"
#include "utilities/CCopasiProblem.h"
#include "commandline/COptionParser.h"
#include "commandline/COptions.h"
#include "function/CFunctionDB.h"
#include "function/CEvaluationTree.h"
#include "function/CFunction.h"

#include "randomGenerator/CRandom.h"
#include "report/CCopasiTimer.h"
#include "report/CKeyFactory.h"

int main(int argc, char *argv[])
{
  try
    {
      // Parse the commandline options
      COptions::init(argc, argv);
    }

  catch (copasi::autoexcept &e)
    {
      switch (e.get_autothrow_id())
        {
        case copasi::autothrow_help:
          std::cout << "Usage: " << argv[0] << " [options]\n";
          std::cout << e.what();
        }

      return 1;
    }

  catch (copasi::option_error &e)
    {
      std::cerr << argv[0] << ": " << e.what() << "\n";
      std::cerr << e.get_help_comment() << std::endl;

      return 1;
    }

  try
    {
      // Create the root container.
      CCopasiContainer::init();

      // Create the global data model.
      CCopasiDataModel::Global = new CCopasiDataModel;

#ifdef XXXX
      CCallParameters<C_FLOAT64> Variables(20);
      unsigned C_INT32 j, i, imax = Variables.size();
      CRandom * pRandom = CRandom::createGenerator();

      for (i = 0; i < imax; i++)
        {
          C_FLOAT64 * pValue = new C_FLOAT64;
          *pValue = 100.0 * pRandom->getRandomOO();
          Variables[i].value = pValue;
        }

      CCopasiTimer * pCPU =
        const_cast<CCopasiTimer *>(static_cast<const CCopasiTimer *>(CCopasiContainer::Root->getObject((std::string)"CN=Root,Timer=CPU Time")));
      CCopasiTimer * pWall =
        const_cast<CCopasiTimer *>(static_cast<const CCopasiTimer *>(CCopasiContainer::Root->getObject((std::string)"CN=Root,Timer=Wall Clock Time")));

      CCopasiVectorN< CEvaluationTree > & Functions =
        CCopasiDataModel::Global->getFunctionList()->loadedFunctions();
      CFunction * pFunction;

      for (i = 0, imax = Functions.size(); i < imax; i++)
        {
          pFunction = dynamic_cast<CFunction *>(Functions[i]);
          if (pFunction->getType() != CEvaluationTree::MassAction)
            for (j = 0; j < 100000; j++)
              pFunction->calcValue(Variables);
        }

      pCPU->actualize();
      pWall->actualize();

      std::cout << "CPU time:  ";
      pCPU->print(&std::cout);
      std::cout << std::endl;

      std::cout << "Wall time: ";
      pWall->print(&std::cout);
      std::cout << std::endl;
#endif // XXXX

#ifdef XXXX
      CEvaluationTree Expression;
      Expression.setInfix("5**-sin(x)");
      Expression.setInfix("a*5.0/-b");
      Expression.setInfix("EXPONENTIALE+b*c");
      Expression.setInfix("4.0*\"PI+b");
      Expression.setInfix("2*(3+b)");
#endif

      const COptions::nonOptionType & Files = COptions::getNonOptions();

      if (!COptions::compareValue("ImportSBML", std::string("")))
        {
          // Import the SBML File
          std::string ImportSBML;
          COptions::getValue("ImportSBML", ImportSBML);
          CCopasiDataModel::Global->importSBML(ImportSBML);

          // Save the COPASI File, which is the only thing to do.
          std::string Save;
          COptions::getValue("Save", Save);
          CCopasiDataModel::Global->saveModel(Save);
        }

      COptions::nonOptionType::const_iterator it = Files.begin();
      COptions::nonOptionType::const_iterator end = Files.end();

      for (; it != end; ++it)
        {
          CCopasiDataModel::Global->loadModel(*it);

          // Check whether exporting to SBML is requested.
          if (!COptions::compareValue("ExportSBML", std::string("")))
            {
              // Export the SBML File
              std::string ExportSBML;
              COptions::getValue("ExportSBML", ExportSBML);
              CCopasiDataModel::Global->exportSBML(ExportSBML);

              // Since only one export file name can be specified we
              // stop execution.
              return 0;
            }

          CCopasiVectorN< CCopasiTask > & TaskList = * CCopasiDataModel::Global->getTaskList();
          unsigned C_INT32 i, imax = TaskList.size();

          for (i = 0; i < imax; i++)
            if (TaskList[i]->isScheduled())
              {
                TaskList[i]->getProblem()->setModel(CCopasiDataModel::Global->getModel());

                TaskList[i]->initialize();
                TaskList[i]->process();
                TaskList[i]->restore();
              }

          // Check whether a file for saving the resulting model is given
          if (!COptions::compareValue("Save", std::string("")))
            {
              std::string Save;
              COptions::getValue("Save", Save);
              CCopasiDataModel::Global->saveModel(Save);

              // Since only one save file name can be specified we
              // stop execution.
              return 0;
            }

          //      CCopasiDataModel::Global->saveModel("");
        }

      //#endif // XXXX
    }

  catch (CCopasiException Exception)
    {
      std::cout << Exception.getMessage().getText() << std::endl;
    }

  pdelete(CCopasiDataModel::Global);
  pdelete(CCopasiContainer::Root);

  //std::cout << "Leaving main program." << std::endl;
  return 0;
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <argp.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include "FatSystem.h"
#include "FatPath.h"
#include "FatChains.h"
#include "FatBackup.h"
#include "FatDiff.h"

using namespace std;

void usage()
{
    cout << "fatcat v1.0, Gregwar <g.passault@gmail.com>" << endl;
    cout << endl;
    cout << "Usage: fatcat [-i] disk.img" << endl;
    cout << "  -i: display information about disk" << endl;
    cout << endl;
    cout << "Browsing & extracting:" << endl;
    cout << "  -l [dir]: list files and directories in the given path" << endl;
    cout << "  -L [cluster]: list files and directories in the given cluster" << endl;
    cout << "  -r [path]: reads the file given by the path" << endl;
    cout << "  -R [cluster]: reads the data from given cluster" << endl;
    cout << "  -s [size]: specify the size of data to read from the cluster" << endl;
    cout << "  -d: enable listing of deleted files" << endl;
    cout << "  -x [directory]: extract all files to a directory, deleted files included if -d" << endl;
    cout << "  -c: enable contiguous mode" << endl;
    cout << endl;
    cout << "FAT Hacking" << endl;
    cout << "  -@ [cluster]: Get the cluster address and informations" << endl;
    cout << "  -2: analysis & compare the 2 FATs" << endl;
    cout << "  -b [file]: backup the FATs" << endl;
    cout << "* -p [file]: restore (patch) the FATs" << endl;
    cout << "* -w [cluster] -v [value]: write next cluster (see -T)" << endl;
    cout << "  -T [table]: specify which table to write (0:both, 1:first, 2:second)" << endl;
    cout << "* -m: merge the FATs" << endl;
    cout << "  -k: analysis the chains" << endl;

    cout << endl;
    cout << "*: These flags writes on the disk, be careful" << endl;
    cout << endl;
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[])
{
    vector<string> arguments;
    char *image = NULL;
    int index;

    // -s, specify the size to be read
    int size = -1;

    // -i, display informations about the disk
    bool infoFlag = false;

    // -l, list directories in the given path
    bool listFlag = false;
    string listPath;

    // -c, listing for a direct cluster
    bool listClusterFlag = false;
    int listCluster;

    // -r, reads a file
    bool readFlag = false;
    string readPath;

    // -t, reads from cluster file
    bool clusterRead = false;
    int cluster;

    // -d, lists deleted
    bool listDeleted = false;

    // -c: contiguous mode
    bool contiguous = false;

    // -x: extract
    bool extract = false;
    string extractDirectory;

    // -2: compare two fats
    bool compare = false;

    // -@: get the cluster address
    bool address = false;

    // -k: analysis the chains
    bool chains = false;

    // -b: backup the fats
    bool backup = false;
    bool patch = false;
    string backupFile;

    // -w: write next cluster
    bool writeNext = false;

    // -m: merge the FATs
    bool merge = false;

    // -v: value
    bool hasValue = false;
    int value;

    // -T: FAT table to write
    int table;

    // Parsing command line
    while ((index = getopt(argc, argv, "il:L:r:R:s:dchx:2@:kb:p:w:v:mT:")) != -1) {
        switch (index) {
            case 'T':
                table = atoi(optarg);
                break;
            case 'm':
                merge = true;
                break;
            case 'v':
                hasValue = true;
                value = atoi(optarg);
                break;
            case 'w':
                writeNext = true;
                cluster = atoi(optarg);
                break;
            case '@':
                address = true;
                cluster = atoi(optarg);
                break;
            case 'k':
                chains = true;
                break;
            case 'i':
                infoFlag = true;
                break;
            case 'l':
                listFlag = true;
                listPath = string(optarg);
                break;
            case 'L':
                listClusterFlag = true;
                listCluster = atoi(optarg);
                break;
            case 'r':
                readFlag = true;
                readPath = string(optarg);
                break;
            case 'R':
                clusterRead = true;
                cluster = atoi(optarg);
                break;
            case 's':
                size = atoi(optarg);
                break;
            case 'd':
                listDeleted = true;
                break;
            case 'c':
                contiguous = true;
                break;
            case 'x':
                extract = true;
                extractDirectory = string(optarg);
                break;
            case '2':
                compare = true;
                break;
            case 'b':
                backup = true;
                backupFile = string(optarg);
                break;
            case 'p':
                patch = true;
                backupFile = string(optarg);
                break;
            case 'h':
                usage();
                break;
        }
    }

    // Trying to get the FAT file or device
    if (optind != argc) {
        image = argv[optind];
    }

    if (!image) {
        usage();
    }

    // Getting extra arguments
    for (index=optind+1; index<argc; index++) {
        arguments.push_back(argv[index]);
    }

    // If the user did not required any actions
    if (!(infoFlag || listFlag || listClusterFlag ||
        readFlag || clusterRead || extract || compare || address ||
        chains || backup || patch || writeNext || merge)) {
        usage();
    }

    try {
        // Openning the image
        FatSystem fat(image);

        fat.setListDeleted(listDeleted);
        fat.setContiguous(contiguous);

        if (fat.init()) {
            if (infoFlag) {
                fat.infos();
            } else if (listFlag) {
                cout << "Listing path " << listPath << endl;
                FatPath path(listPath);
                fat.list(path);
            } else if (listClusterFlag) {
                cout << "Listing cluster " << listCluster << endl;
                fat.list(listCluster);
            } else if (readFlag) {
                FatPath path(readPath);
                fat.readFile(path);
            } else if (clusterRead) {
                fat.readFile(cluster, size);
            } else if (extract) {
                fat.extract(extractDirectory);
            } else if (compare) {
                FatDiff diff(fat);
                diff.compare();
            } else if (address) {
                cout << "Cluster " << cluster << " address:" << endl;
                int addr = fat.clusterAddress(cluster);
                int next1 = fat.nextCluster(cluster, 0);
                int next2 = fat.nextCluster(cluster, 1);
                printf("%d (%08x)\n", addr, addr);
                cout << "Next cluster:" << endl;
                printf("FAT1: %u (%08x)\n", next1, next1);
                printf("FAT2: %u (%08x)\n", next2, next2);
            } else if (chains) {
                FatChains chains(fat);
                chains.findChains();
            } else if (backup || patch) {
                FatBackup backupSystem(fat);

                if (backup) {
                    backupSystem.backup(backupFile);
                } else {
                    backupSystem.patch(backupFile);
                }
            } else if (writeNext) {
                if (!hasValue) {
                    throw string("You should provide a value with -v");
                }

                int prev = fat.nextCluster(cluster);
                printf("Writing next cluster of %u from %u to %u\n", cluster, prev, value);
                fat.enableWrite();

                if (table == 0 || table == 1) {
                    printf("Writing on FAT1\n");
                    fat.writeNextCluster(cluster, value, 0);
                }
                if (table == 0 || table == 2) {
                    printf("Writing on FAT2\n");
                    fat.writeNextCluster(cluster, value, 1);
                }
            } else if (merge) {
                FatDiff diff(fat);
                diff.merge();
            }
        } else {
            cout << "! Failed to init the FAT filesystem" << endl;
        }

        fat.enableWrite();
        for (int i=0; i<fat.totalClusters/2; i++) {
            fat.writeNextCluster(i, 0xffffffff, 0);
        }
    } catch (string error) {
        cerr << "Error: " << error << endl;
    }

    exit(EXIT_SUCCESS);
}
<commit_msg>Removing mistake commit<commit_after>#include <stdlib.h>
#include <argp.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include "FatSystem.h"
#include "FatPath.h"
#include "FatChains.h"
#include "FatBackup.h"
#include "FatDiff.h"

using namespace std;

void usage()
{
    cout << "fatcat v1.0, Gregwar <g.passault@gmail.com>" << endl;
    cout << endl;
    cout << "Usage: fatcat [-i] disk.img" << endl;
    cout << "  -i: display information about disk" << endl;
    cout << endl;
    cout << "Browsing & extracting:" << endl;
    cout << "  -l [dir]: list files and directories in the given path" << endl;
    cout << "  -L [cluster]: list files and directories in the given cluster" << endl;
    cout << "  -r [path]: reads the file given by the path" << endl;
    cout << "  -R [cluster]: reads the data from given cluster" << endl;
    cout << "  -s [size]: specify the size of data to read from the cluster" << endl;
    cout << "  -d: enable listing of deleted files" << endl;
    cout << "  -x [directory]: extract all files to a directory, deleted files included if -d" << endl;
    cout << "  -c: enable contiguous mode" << endl;
    cout << endl;
    cout << "FAT Hacking" << endl;
    cout << "  -@ [cluster]: Get the cluster address and informations" << endl;
    cout << "  -2: analysis & compare the 2 FATs" << endl;
    cout << "  -b [file]: backup the FATs" << endl;
    cout << "* -p [file]: restore (patch) the FATs" << endl;
    cout << "* -w [cluster] -v [value]: write next cluster (see -T)" << endl;
    cout << "  -T [table]: specify which table to write (0:both, 1:first, 2:second)" << endl;
    cout << "* -m: merge the FATs" << endl;
    cout << "  -k: analysis the chains" << endl;

    cout << endl;
    cout << "*: These flags writes on the disk, be careful" << endl;
    cout << endl;
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[])
{
    vector<string> arguments;
    char *image = NULL;
    int index;

    // -s, specify the size to be read
    int size = -1;

    // -i, display informations about the disk
    bool infoFlag = false;

    // -l, list directories in the given path
    bool listFlag = false;
    string listPath;

    // -c, listing for a direct cluster
    bool listClusterFlag = false;
    int listCluster;

    // -r, reads a file
    bool readFlag = false;
    string readPath;

    // -t, reads from cluster file
    bool clusterRead = false;
    int cluster;

    // -d, lists deleted
    bool listDeleted = false;

    // -c: contiguous mode
    bool contiguous = false;

    // -x: extract
    bool extract = false;
    string extractDirectory;

    // -2: compare two fats
    bool compare = false;

    // -@: get the cluster address
    bool address = false;

    // -k: analysis the chains
    bool chains = false;

    // -b: backup the fats
    bool backup = false;
    bool patch = false;
    string backupFile;

    // -w: write next cluster
    bool writeNext = false;

    // -m: merge the FATs
    bool merge = false;

    // -v: value
    bool hasValue = false;
    int value;

    // -T: FAT table to write
    int table;

    // Parsing command line
    while ((index = getopt(argc, argv, "il:L:r:R:s:dchx:2@:kb:p:w:v:mT:")) != -1) {
        switch (index) {
            case 'T':
                table = atoi(optarg);
                break;
            case 'm':
                merge = true;
                break;
            case 'v':
                hasValue = true;
                value = atoi(optarg);
                break;
            case 'w':
                writeNext = true;
                cluster = atoi(optarg);
                break;
            case '@':
                address = true;
                cluster = atoi(optarg);
                break;
            case 'k':
                chains = true;
                break;
            case 'i':
                infoFlag = true;
                break;
            case 'l':
                listFlag = true;
                listPath = string(optarg);
                break;
            case 'L':
                listClusterFlag = true;
                listCluster = atoi(optarg);
                break;
            case 'r':
                readFlag = true;
                readPath = string(optarg);
                break;
            case 'R':
                clusterRead = true;
                cluster = atoi(optarg);
                break;
            case 's':
                size = atoi(optarg);
                break;
            case 'd':
                listDeleted = true;
                break;
            case 'c':
                contiguous = true;
                break;
            case 'x':
                extract = true;
                extractDirectory = string(optarg);
                break;
            case '2':
                compare = true;
                break;
            case 'b':
                backup = true;
                backupFile = string(optarg);
                break;
            case 'p':
                patch = true;
                backupFile = string(optarg);
                break;
            case 'h':
                usage();
                break;
        }
    }

    // Trying to get the FAT file or device
    if (optind != argc) {
        image = argv[optind];
    }

    if (!image) {
        usage();
    }

    // Getting extra arguments
    for (index=optind+1; index<argc; index++) {
        arguments.push_back(argv[index]);
    }

    // If the user did not required any actions
    if (!(infoFlag || listFlag || listClusterFlag ||
        readFlag || clusterRead || extract || compare || address ||
        chains || backup || patch || writeNext || merge)) {
        usage();
    }

    try {
        // Openning the image
        FatSystem fat(image);

        fat.setListDeleted(listDeleted);
        fat.setContiguous(contiguous);

        if (fat.init()) {
            if (infoFlag) {
                fat.infos();
            } else if (listFlag) {
                cout << "Listing path " << listPath << endl;
                FatPath path(listPath);
                fat.list(path);
            } else if (listClusterFlag) {
                cout << "Listing cluster " << listCluster << endl;
                fat.list(listCluster);
            } else if (readFlag) {
                FatPath path(readPath);
                fat.readFile(path);
            } else if (clusterRead) {
                fat.readFile(cluster, size);
            } else if (extract) {
                fat.extract(extractDirectory);
            } else if (compare) {
                FatDiff diff(fat);
                diff.compare();
            } else if (address) {
                cout << "Cluster " << cluster << " address:" << endl;
                int addr = fat.clusterAddress(cluster);
                int next1 = fat.nextCluster(cluster, 0);
                int next2 = fat.nextCluster(cluster, 1);
                printf("%d (%08x)\n", addr, addr);
                cout << "Next cluster:" << endl;
                printf("FAT1: %u (%08x)\n", next1, next1);
                printf("FAT2: %u (%08x)\n", next2, next2);
            } else if (chains) {
                FatChains chains(fat);
                chains.findChains();
            } else if (backup || patch) {
                FatBackup backupSystem(fat);

                if (backup) {
                    backupSystem.backup(backupFile);
                } else {
                    backupSystem.patch(backupFile);
                }
            } else if (writeNext) {
                if (!hasValue) {
                    throw string("You should provide a value with -v");
                }

                int prev = fat.nextCluster(cluster);
                printf("Writing next cluster of %u from %u to %u\n", cluster, prev, value);
                fat.enableWrite();

                if (table == 0 || table == 1) {
                    printf("Writing on FAT1\n");
                    fat.writeNextCluster(cluster, value, 0);
                }
                if (table == 0 || table == 2) {
                    printf("Writing on FAT2\n");
                    fat.writeNextCluster(cluster, value, 1);
                }
            } else if (merge) {
                FatDiff diff(fat);
                diff.merge();
            }
        } else {
            cout << "! Failed to init the FAT filesystem" << endl;
        }
    } catch (string error) {
        cerr << "Error: " << error << endl;
    }

    exit(EXIT_SUCCESS);
}
<|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "attribute_reprocessing_initializer.h"
#include <vespa/searchcore/proton/attribute/attribute_populator.h>
#include <vespa/searchcore/proton/attribute/document_field_populator.h>
#include <vespa/searchcore/proton/attribute/filter_attribute_manager.h>
#include <vespa/searchcore/proton/common/i_indexschema_inspector.h>
#include <vespa/searchlib/attribute/attributevector.h>

#include <vespa/log/log.h>
LOG_SETUP(".proton.reprocessing.attribute_reprocessing_initializer");

using namespace search::index;
using search::AttributeGuard;
using search::AttributeVector;
using search::SerialNum;
using search::index::schema::DataType;
using search::attribute::BasicType;

namespace proton {

typedef AttributeReprocessingInitializer::Config ARIConfig;

namespace {

constexpr search::SerialNum ATTRIBUTE_INIT_SERIAL = 1;

const char *
toStr(bool value)
{
    return (value ? "true" : "false");
}

bool fastPartialUpdateAttribute(BasicType::Type attrType) {
    // Partial update to tensor or predicate attribute must update document
    return ((attrType != BasicType::Type::PREDICATE) &&
            (attrType != BasicType::Type::TENSOR) &&
            (attrType != BasicType::Type::REFERENCE));
}

bool isStructFieldAttribute(const vespalib::string &name) {
    return name.find('.') != vespalib::string::npos;
}

FilterAttributeManager::AttributeSet
getAttributeSetToPopulate(const ARIConfig &newCfg,
                          const ARIConfig &oldCfg,
                          const IDocumentTypeInspector &inspector,
                          search::SerialNum serialNum)
{
    FilterAttributeManager::AttributeSet attrsToPopulate;
    std::vector<AttributeGuard> attrList;
    newCfg.getAttrMgr()->getAttributeList(attrList);
    for (const auto &guard : attrList) {
        const vespalib::string &name = guard->getName();
        bool inOldAttrMgr = oldCfg.getAttrMgr()->getAttribute(name)->valid();
        bool unchangedField = inspector.hasUnchangedField(name);
        search::SerialNum flushedSerialNum = newCfg.getAttrMgr()->getFlushedSerialNum(name);
        bool populateAttribute = !inOldAttrMgr && unchangedField && (flushedSerialNum < serialNum);
        LOG(debug, "getAttributeSetToPopulate(): name='%s', inOldAttrMgr=%s, unchangedField=%s, populate=%s",
                name.c_str(), toStr(inOldAttrMgr), toStr(unchangedField), toStr(populateAttribute));
        if (populateAttribute) {
            attrsToPopulate.insert(name);
        }
    }
    return attrsToPopulate;
}

IReprocessingReader::SP
getAttributesToPopulate(const ARIConfig &newCfg,
                        const ARIConfig &oldCfg,
                        const IDocumentTypeInspector &inspector,
                        const vespalib::string &subDbName,
                        search::SerialNum serialNum)
{
    FilterAttributeManager::AttributeSet attrsToPopulate =
        getAttributeSetToPopulate(newCfg, oldCfg, inspector, serialNum);
    if (!attrsToPopulate.empty()) {
        return IReprocessingReader::SP(new AttributePopulator
                (IAttributeManager::SP(new FilterAttributeManager
                        (attrsToPopulate, newCfg.getAttrMgr())),
                        ATTRIBUTE_INIT_SERIAL, subDbName, serialNum));
    }
    return IReprocessingReader::SP();
}

std::vector<IReprocessingRewriter::SP>
getFieldsToPopulate(const ARIConfig &newCfg,
                    const ARIConfig &oldCfg,
                    const IDocumentTypeInspector &inspector,
                    const IIndexschemaInspector &oldIndexschemaInspector,
                    const vespalib::string &subDbName)
{
    std::vector<IReprocessingRewriter::SP> fieldsToPopulate;
    std::vector<AttributeGuard> attrList;
    oldCfg.getAttrMgr()->getAttributeList(attrList);
    for (const auto &guard : attrList) {
        const vespalib::string &name = guard->getName();
        BasicType attrType(guard->getConfig().basicType());
        bool inNewAttrMgr = newCfg.getAttrMgr()->getAttribute(name)->valid();
        bool unchangedField = inspector.hasUnchangedField(name);
        // NOTE: If it is a string and index field we shall
        // keep the original in order to preserve annotations.
        bool wasStringIndexField = oldIndexschemaInspector.isStringIndex(name);
        bool populateField = !inNewAttrMgr && unchangedField && !wasStringIndexField &&
                             fastPartialUpdateAttribute(attrType.type()) &&
                             !isStructFieldAttribute(name);
        LOG(debug, "getFieldsToPopulate(): name='%s', inNewAttrMgr=%s, unchangedField=%s, "
                "wasStringIndexField=%s, dataType=%s, populate=%s",
                name.c_str(), toStr(inNewAttrMgr), toStr(unchangedField),
            toStr(wasStringIndexField),
            attrType.asString(),
            toStr(populateField));
        if (populateField) {
            fieldsToPopulate.push_back(IReprocessingRewriter::SP
                    (new DocumentFieldPopulator(name,
                            guard.getSP(), subDbName)));
        }
    }
    return fieldsToPopulate;
}

}

AttributeReprocessingInitializer::
AttributeReprocessingInitializer(const Config &newCfg,
                                 const Config &oldCfg,
                                 const IDocumentTypeInspector &inspector,
                                 const IIndexschemaInspector &oldIndexschemaInspector,
                                 const vespalib::string &subDbName,
                                 search::SerialNum serialNum)
    : _attrsToPopulate(getAttributesToPopulate(newCfg, oldCfg, inspector, subDbName, serialNum)),
      _fieldsToPopulate(getFieldsToPopulate(newCfg, oldCfg, inspector, oldIndexschemaInspector, subDbName))
{
}

bool
AttributeReprocessingInitializer::hasReprocessors() const
{
    return _attrsToPopulate.get() != nullptr || !_fieldsToPopulate.empty();
}

void
AttributeReprocessingInitializer::initialize(IReprocessingHandler &handler)
{
    if (_attrsToPopulate.get() != nullptr) {
        handler.addReader(_attrsToPopulate);
    }
    if (!_fieldsToPopulate.empty()) {
        for (const auto &rewriter : _fieldsToPopulate) {
            handler.addRewriter(rewriter);
        }
    }
}

} // namespace proton
<commit_msg>std::make_shared<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "attribute_reprocessing_initializer.h"
#include <vespa/searchcore/proton/attribute/attribute_populator.h>
#include <vespa/searchcore/proton/attribute/document_field_populator.h>
#include <vespa/searchcore/proton/attribute/filter_attribute_manager.h>
#include <vespa/searchcore/proton/common/i_indexschema_inspector.h>
#include <vespa/searchlib/attribute/attributevector.h>

#include <vespa/log/log.h>
LOG_SETUP(".proton.reprocessing.attribute_reprocessing_initializer");

using namespace search::index;
using search::AttributeGuard;
using search::AttributeVector;
using search::SerialNum;
using search::index::schema::DataType;
using search::attribute::BasicType;

namespace proton {

typedef AttributeReprocessingInitializer::Config ARIConfig;

namespace {

constexpr search::SerialNum ATTRIBUTE_INIT_SERIAL = 1;

const char *
toStr(bool value)
{
    return (value ? "true" : "false");
}

bool fastPartialUpdateAttribute(BasicType::Type attrType) {
    // Partial update to tensor or predicate attribute must update document
    return ((attrType != BasicType::Type::PREDICATE) &&
            (attrType != BasicType::Type::TENSOR) &&
            (attrType != BasicType::Type::REFERENCE));
}

bool isStructFieldAttribute(const vespalib::string &name) {
    return name.find('.') != vespalib::string::npos;
}

FilterAttributeManager::AttributeSet
getAttributeSetToPopulate(const ARIConfig &newCfg,
                          const ARIConfig &oldCfg,
                          const IDocumentTypeInspector &inspector,
                          search::SerialNum serialNum)
{
    FilterAttributeManager::AttributeSet attrsToPopulate;
    std::vector<AttributeGuard> attrList;
    newCfg.getAttrMgr()->getAttributeList(attrList);
    for (const auto &guard : attrList) {
        const vespalib::string &name = guard->getName();
        bool inOldAttrMgr = oldCfg.getAttrMgr()->getAttribute(name)->valid();
        bool unchangedField = inspector.hasUnchangedField(name);
        search::SerialNum flushedSerialNum = newCfg.getAttrMgr()->getFlushedSerialNum(name);
        bool populateAttribute = !inOldAttrMgr && unchangedField && (flushedSerialNum < serialNum);
        LOG(debug, "getAttributeSetToPopulate(): name='%s', inOldAttrMgr=%s, unchangedField=%s, populate=%s",
                name.c_str(), toStr(inOldAttrMgr), toStr(unchangedField), toStr(populateAttribute));
        if (populateAttribute) {
            attrsToPopulate.insert(name);
        }
    }
    return attrsToPopulate;
}

IReprocessingReader::SP
getAttributesToPopulate(const ARIConfig &newCfg,
                        const ARIConfig &oldCfg,
                        const IDocumentTypeInspector &inspector,
                        const vespalib::string &subDbName,
                        search::SerialNum serialNum)
{
    FilterAttributeManager::AttributeSet attrsToPopulate =
        getAttributeSetToPopulate(newCfg, oldCfg, inspector, serialNum);
    if (!attrsToPopulate.empty()) {
        return std::make_shared<AttributePopulator>
                (std::make_shared<FilterAttributeManager>(attrsToPopulate, newCfg.getAttrMgr()),
                 ATTRIBUTE_INIT_SERIAL, subDbName, serialNum);
    }
    return IReprocessingReader::SP();
}

std::vector<IReprocessingRewriter::SP>
getFieldsToPopulate(const ARIConfig &newCfg,
                    const ARIConfig &oldCfg,
                    const IDocumentTypeInspector &inspector,
                    const IIndexschemaInspector &oldIndexschemaInspector,
                    const vespalib::string &subDbName)
{
    std::vector<IReprocessingRewriter::SP> fieldsToPopulate;
    std::vector<AttributeGuard> attrList;
    oldCfg.getAttrMgr()->getAttributeList(attrList);
    for (const auto &guard : attrList) {
        const vespalib::string &name = guard->getName();
        BasicType attrType(guard->getConfig().basicType());
        bool inNewAttrMgr = newCfg.getAttrMgr()->getAttribute(name)->valid();
        bool unchangedField = inspector.hasUnchangedField(name);
        // NOTE: If it is a string and index field we shall
        // keep the original in order to preserve annotations.
        bool wasStringIndexField = oldIndexschemaInspector.isStringIndex(name);
        bool populateField = !inNewAttrMgr && unchangedField && !wasStringIndexField &&
                             fastPartialUpdateAttribute(attrType.type()) &&
                             !isStructFieldAttribute(name);
        LOG(debug, "getFieldsToPopulate(): name='%s', inNewAttrMgr=%s, unchangedField=%s, "
                "wasStringIndexField=%s, dataType=%s, populate=%s",
                name.c_str(), toStr(inNewAttrMgr), toStr(unchangedField),
            toStr(wasStringIndexField),
            attrType.asString(),
            toStr(populateField));
        if (populateField) {
            fieldsToPopulate.push_back(IReprocessingRewriter::SP
                    (new DocumentFieldPopulator(name,
                            guard.getSP(), subDbName)));
        }
    }
    return fieldsToPopulate;
}

}

AttributeReprocessingInitializer::
AttributeReprocessingInitializer(const Config &newCfg,
                                 const Config &oldCfg,
                                 const IDocumentTypeInspector &inspector,
                                 const IIndexschemaInspector &oldIndexschemaInspector,
                                 const vespalib::string &subDbName,
                                 search::SerialNum serialNum)
    : _attrsToPopulate(getAttributesToPopulate(newCfg, oldCfg, inspector, subDbName, serialNum)),
      _fieldsToPopulate(getFieldsToPopulate(newCfg, oldCfg, inspector, oldIndexschemaInspector, subDbName))
{
}

bool
AttributeReprocessingInitializer::hasReprocessors() const
{
    return _attrsToPopulate.get() != nullptr || !_fieldsToPopulate.empty();
}

void
AttributeReprocessingInitializer::initialize(IReprocessingHandler &handler)
{
    if (_attrsToPopulate.get() != nullptr) {
        handler.addReader(_attrsToPopulate);
    }
    if (!_fieldsToPopulate.empty()) {
        for (const auto &rewriter : _fieldsToPopulate) {
            handler.addRewriter(rewriter);
        }
    }
}

} // namespace proton
<|endoftext|>


<commit_before>/*
  Original code from tekkies/CVdrone (get actual address from github)

  Modified by Elliot Greenlee, Caleb Mennen, Jacob Pollack
  COSC 402 Senior Design

  Min Kao Drone Tour
  See readme at (get actual address from github)
*/

#include "ardrone/ardrone.h"
#include "control.h"
#include "structures.h"
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(int argc, char *argv[]) {
  Control *control;
  int wait = 33;

  try {
    //Initialize main control variables and flight modes
    control = new Control();
  } catch (const char *msg) {
    cout << msg << endl;
    return -1;
  }

  // Setting up for constant time
  double time_counter = 0;
  clock_t this_time = clock();
  clock_t last_time = this_time;
  long long executions = 0;
  // Main loop
  while (1) {

    //Time stuff
    this_time = clock();
    time_counter += (double) (this_time - last_time);
    last_time = this_time;
    executions++;

    double time_delay = 1.0 / 25;
    if (time_counter < (time_delay * CLOCKS_PER_SEC)) { //AKA not enough time has passed
      continue;
    }
    time_counter -= time_delay * CLOCKS_PER_SEC;

    printf("I hit %lli times\n", executions);
    executions = 0;
//    exit(0);

    //Detect user key input and end loop if ESC is pressed
    if (!control->getKey(wait)) break;

    control->detectFlyingMode(); //b, n, m to change mode
    control->changeSpeed(); //0-9 to change speed
    control->detectTakeoff(); //spacebar to take off

    //Get the image from the camera
    control->getImage();

    //Run drone control
    control->fly();

    //Display image overlay values
    control->overlayControl();

    //Send move command to the drone
    control->move();
  }

  //Close flying modes and drone connection
  control->close();

  return 0;
}
<commit_msg>restrict main to execute only 25 times a second<commit_after>/*
  Original code from tekkies/CVdrone (get actual address from github)

  Modified by Elliot Greenlee, Caleb Mennen, Jacob Pollack
  COSC 402 Senior Design

  Min Kao Drone Tour
  See readme at (get actual address from github)
*/

#include "ardrone/ardrone.h"
#include "control.h"
#include "structures.h"
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(int argc, char *argv[]) {
  Control *control;
  int wait = 33;

  try {
    //Initialize main control variables and flight modes
    control = new Control();
  } catch (const char *msg) {
    cout << msg << endl;
    return -1;
  }

  // Setting up for constant time
  double time_counter = 0;
  clock_t this_time = clock();
  clock_t last_time = this_time;
  long long executions = 0;
  // Main loop
  while (1) {

    //Time stuff
    this_time = clock();
    time_counter += (double) (this_time - last_time);
    last_time = this_time;
    executions++;

    double time_delay = 1.0 / 25;
    if (time_counter < (time_delay * CLOCKS_PER_SEC)) { //AKA not enough time has passed
      continue;
    }
    time_counter -= time_delay * CLOCKS_PER_SEC;

//    printf("I hit %lli times\n", executions);
    executions = 0;
//    exit(0);

    //Detect user key input and end loop if ESC is pressed
    if (!control->getKey(wait)) break;

    control->detectFlyingMode(); //b, n, m to change mode
    control->changeSpeed(); //0-9 to change speed
    control->detectTakeoff(); //spacebar to take off

    //Get the image from the camera
    control->getImage();

    //Run drone control
    control->fly();

    //Display image overlay values
    control->overlayControl();

    //Send move command to the drone
    control->move();
  }

  //Close flying modes and drone connection
  control->close();

  return 0;
}
<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "precomp.hpp"
#include "opencv2/hal/intrin.hpp"

namespace cv
{

void spatialGradient( InputArray _src, OutputArray _dx, OutputArray _dy, int ksize )
{

    // Prepare InputArray src
    Mat src = _src.getMat();
    CV_Assert( !src.empty() );
    CV_Assert( src.isContinuous() );
    CV_Assert( src.type() == CV_8UC1 );

    // Prepare OutputArrays dx, dy
    _dx.create( src.size(), CV_16SC1 );
    _dy.create( src.size(), CV_16SC1 );
    Mat dx = _dx.getMat(),
        dy = _dy.getMat();
    CV_Assert( dx.isContinuous() );
    CV_Assert( dy.isContinuous() );

    // TODO: Allow for other kernel sizes
    CV_Assert(ksize == 3);

    // Reference
    //Sobel( src, dx, CV_16SC1, 1, 0, ksize );
    //Sobel( src, dy, CV_16SC1, 0, 1, ksize );

    // Get dimensions
    int H = src.rows,
        W = src.cols,
        N = H * W;

    // Get raw pointers to input/output data
    uchar* p_src = src.ptr<uchar>(0);
    short* p_dx = dx.ptr<short>(0);
    short* p_dy = dy.ptr<short>(0);

    // Row, column indices
    int i, j;

    /* NOTE:
     *
     * Sobel-x: -1  0  1
     *          -2  0  2
     *          -1  0  1
     *
     * Sobel-y: -1 -2 -1
     *           0  0  0
     *           1  2  1
     */

    // No-SSE
    int idx;

    p_dx[0] = 0;   // Top-left corner
    p_dy[0] = 0;
    p_dx[W-1] = 0; // Top-right corner
    p_dy[W-1] = 0;
    p_dx[N-1] = 0; // Bottom-right corner
    p_dy[N-1] = 0;
    p_dx[N-W] = 0; // Bottom-left corner
    p_dy[N-W] = 0;

    // Handle special case: column matrix
    if ( W == 1 )
    {
        for ( i = 1; i < H - 1; i++ )
        {
            p_dx[i] = 0;
            p_dy[i] = 4*(p_src[i + 1] - p_src[i - 1]); // Should be 2?! 4 makes tests pass
        }
        return;
    }

    // Handle special case: row matrix
    if ( H == 1 )
    {
        for ( j = 1; j < W - 1; j++ )
        {
            p_dx[j] = 4*(p_src[j + 1] - p_src[j - 1]); // Should be 2?! 4 makes tests pass
            p_dy[j] = 0;
        }
        return;
    }

    // Do top row
    for ( j = 1; j < W - 1; j++ )
    {
        idx = j;
        p_dx[idx] = -(p_src[idx+W-1] + 2*p_src[idx-1] + p_src[idx+W-1]) +
                     (p_src[idx+W+1] + 2*p_src[idx+1] + p_src[idx+W+1]);
        p_dy[idx] = 0;
    }

    // Do right column
    idx = 2*W - 1;
    for ( i = 1; i < H - 1; i++ )
    {
        p_dx[idx] = 0;
        p_dy[idx] = -(p_src[idx-W-1] + 2*p_src[idx-W] + p_src[idx-W-1]) +
                     (p_src[idx+W-1] + 2*p_src[idx+W] + p_src[idx+W-1]);
        idx += W;
    }

    // Do bottom row
    idx = N - W + 1;
    for ( j = 1; j < W - 1; j++ )
    {
        p_dx[idx] = -(p_src[idx-W-1] + 2*p_src[idx-1] + p_src[idx-W-1]) +
                     (p_src[idx-W+1] + 2*p_src[idx+1] + p_src[idx-W+1]);
        p_dy[idx] = 0;
        idx++;
    }

    // Do left column
    idx = W;
    for ( i = 1; i < H - 1; i++ )
    {
        p_dx[idx] = 0;
        p_dy[idx] = -(p_src[idx-W+1] + 2*p_src[idx-W] + p_src[idx-W+1]) +
                     (p_src[idx+W+1] + 2*p_src[idx+W] + p_src[idx+W+1]);
        idx += W;
    }

    // Do Inner area
#if CV_SIMD128
    // Characters in variable names have the following meanings:
    // u: unsigned char
    // s: signed int
    //
    // [row][column]
    // m: offset -1
    // n: offset  0
    // p: offset  1
    // Example: umn is offset -1 in row and offset 0 in column
    v_uint8x16 v_umm, v_umn, v_ump,
               v_unm, v_unn, v_unp,
               v_upm, v_upn, v_upp;
    v_uint16x8 v_umm1, v_umm2, v_umn1, v_umn2, v_ump1, v_ump2,
               v_unm1, v_unm2, v_unn1, v_unn2, v_unp1, v_unp2,
               v_upm1, v_upm2, v_upn1, v_upn2, v_upp1, v_upp2;
    v_int16x8 v_smm1, v_smm2, v_smn1, v_smn2, v_smp1, v_smp2,
              v_snm1, v_snm2, v_snn1, v_snn2, v_snp1, v_snp2,
              v_spm1, v_spm2, v_spn1, v_spn2, v_spp1, v_spp2,
              v_two = v_setall_s16(2),
              v_sdx1, v_sdx2, v_sdy1, v_sdy2;
    for ( i = 1; i < H - 1; i++ )
    for ( j = 1; j < W - 1 - 15; j += 16 )
    {
        // Load
        idx = i*W + j;
        v_umm = v_load(&p_src[idx - W - 1]);
        v_umn = v_load(&p_src[idx - W]);
        v_ump = v_load(&p_src[idx - W + 1]);
        v_unm = v_load(&p_src[idx - 1]);
        v_unn = v_load(&p_src[idx]);
        v_unp = v_load(&p_src[idx + 1]);
        v_upm = v_load(&p_src[idx + W - 1]);
        v_upn = v_load(&p_src[idx + W]);
        v_upp = v_load(&p_src[idx + W + 1]);

        // Expand to uint
        v_expand(v_umm, v_umm1, v_umm2);
        v_expand(v_umn, v_umn1, v_umn2);
        v_expand(v_ump, v_ump1, v_ump2);
        v_expand(v_unm, v_unm1, v_unm2);
        v_expand(v_unn, v_unn1, v_unn2);
        v_expand(v_unp, v_unp1, v_unp2);
        v_expand(v_upm, v_upm1, v_upm2);
        v_expand(v_upn, v_upn1, v_upn2);
        v_expand(v_upp, v_upp1, v_upp2);

        // Convert to int
        v_smm1 = v_reinterpret_as_s16(v_umm1);
        v_smm2 = v_reinterpret_as_s16(v_umm2);
        v_smn1 = v_reinterpret_as_s16(v_umn1);
        v_smn2 = v_reinterpret_as_s16(v_umn2);
        v_smp1 = v_reinterpret_as_s16(v_ump1);
        v_smp2 = v_reinterpret_as_s16(v_ump2);
        v_snm1 = v_reinterpret_as_s16(v_unm1);
        v_snm2 = v_reinterpret_as_s16(v_unm2);
        v_snn1 = v_reinterpret_as_s16(v_unn1);
        v_snn2 = v_reinterpret_as_s16(v_unn2);
        v_snp1 = v_reinterpret_as_s16(v_unp1);
        v_snp2 = v_reinterpret_as_s16(v_unp2);
        v_spm1 = v_reinterpret_as_s16(v_upm1);
        v_spm2 = v_reinterpret_as_s16(v_upm2);
        v_spn1 = v_reinterpret_as_s16(v_upn1);
        v_spn2 = v_reinterpret_as_s16(v_upn2);
        v_spp1 = v_reinterpret_as_s16(v_upp1);
        v_spp2 = v_reinterpret_as_s16(v_upp2);

        // dx
        v_sdx1 = (v_smp1 - v_smm1) + v_two*(v_snp1 - v_snm1) + (v_spp1 - v_spm1);
        v_sdx2 = (v_smp2 - v_smm2) + v_two*(v_snp2 - v_snm2) + (v_spp2 - v_spm2);

        // dy
        v_sdy1 = (v_spm1 - v_smm1) + v_two*(v_spn1 - v_smn1) + (v_spp1 - v_smp1);
        v_sdy2 = (v_spm2 - v_smm2) + v_two*(v_spn2 - v_smn2) + (v_spp2 - v_smp2);

        // Store
        v_store(&p_dx[idx],   v_sdx1);
        v_store(&p_dx[idx+8], v_sdx2);
        v_store(&p_dy[idx],   v_sdy1);
        v_store(&p_dy[idx+8], v_sdy2);
    }

    // Cleanup
    int end_j = j;
    for ( i = 1; i < H - 1; i++ )
    for ( j = end_j; j < W - 1; j++ )
    {
        idx = i*W + j;
        p_dx[idx] = -(p_src[idx-W-1] + 2*p_src[idx-1] + p_src[idx+W-1]) +
                     (p_src[idx-W+1] + 2*p_src[idx+1] + p_src[idx+W+1]);
        p_dy[idx] = -(p_src[idx-W-1] + 2*p_src[idx-W] + p_src[idx-W+1]) +
                     (p_src[idx+W-1] + 2*p_src[idx+W] + p_src[idx+W+1]);
    }
#else
    for ( i = 1; i < H - 1; i++ )
    for ( j = 1; j < W - 1; j++ )
    {
        idx = i*W + j;
        p_dx[idx] = -(p_src[idx-W-1] + 2*p_src[idx-1] + p_src[idx+W-1]) +
                     (p_src[idx-W+1] + 2*p_src[idx+1] + p_src[idx+W+1]);
        p_dy[idx] = -(p_src[idx-W-1] + 2*p_src[idx-W] + p_src[idx-W+1]) +
                     (p_src[idx+W-1] + 2*p_src[idx+W] + p_src[idx+W+1]);
    }
#endif

}

}
<commit_msg>spatialGradient: Less vector loads<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "precomp.hpp"
#include "opencv2/hal/intrin.hpp"

namespace cv
{

void spatialGradient( InputArray _src, OutputArray _dx, OutputArray _dy, int ksize )
{

    // Prepare InputArray src
    Mat src = _src.getMat();
    CV_Assert( !src.empty() );
    CV_Assert( src.isContinuous() );
    CV_Assert( src.type() == CV_8UC1 );

    // Prepare OutputArrays dx, dy
    _dx.create( src.size(), CV_16SC1 );
    _dy.create( src.size(), CV_16SC1 );
    Mat dx = _dx.getMat(),
        dy = _dy.getMat();
    CV_Assert( dx.isContinuous() );
    CV_Assert( dy.isContinuous() );

    // TODO: Allow for other kernel sizes
    CV_Assert(ksize == 3);

    // Reference
    //Sobel( src, dx, CV_16SC1, 1, 0, ksize );
    //Sobel( src, dy, CV_16SC1, 0, 1, ksize );

    // Get dimensions
    int H = src.rows,
        W = src.cols,
        N = H * W;

    // Get raw pointers to input/output data
    uchar* p_src = src.ptr<uchar>(0);
    short* p_dx = dx.ptr<short>(0);
    short* p_dy = dy.ptr<short>(0);

    // Row, column indices
    int i, j;

    /* NOTE:
     *
     * Sobel-x: -1  0  1
     *          -2  0  2
     *          -1  0  1
     *
     * Sobel-y: -1 -2 -1
     *           0  0  0
     *           1  2  1
     */

    // No-SSE
    int idx;

    p_dx[0] = 0;   // Top-left corner
    p_dy[0] = 0;
    p_dx[W-1] = 0; // Top-right corner
    p_dy[W-1] = 0;
    p_dx[N-1] = 0; // Bottom-right corner
    p_dy[N-1] = 0;
    p_dx[N-W] = 0; // Bottom-left corner
    p_dy[N-W] = 0;

    // Handle special case: column matrix
    if ( W == 1 )
    {
        for ( i = 1; i < H - 1; i++ )
        {
            p_dx[i] = 0;
            p_dy[i] = 4*(p_src[i + 1] - p_src[i - 1]); // Should be 2?! 4 makes tests pass
        }
        return;
    }

    // Handle special case: row matrix
    if ( H == 1 )
    {
        for ( j = 1; j < W - 1; j++ )
        {
            p_dx[j] = 4*(p_src[j + 1] - p_src[j - 1]); // Should be 2?! 4 makes tests pass
            p_dy[j] = 0;
        }
        return;
    }

    // Do top row
    for ( j = 1; j < W - 1; j++ )
    {
        idx = j;
        p_dx[idx] = -(p_src[idx+W-1] + 2*p_src[idx-1] + p_src[idx+W-1]) +
                     (p_src[idx+W+1] + 2*p_src[idx+1] + p_src[idx+W+1]);
        p_dy[idx] = 0;
    }

    // Do right column
    idx = 2*W - 1;
    for ( i = 1; i < H - 1; i++ )
    {
        p_dx[idx] = 0;
        p_dy[idx] = -(p_src[idx-W-1] + 2*p_src[idx-W] + p_src[idx-W-1]) +
                     (p_src[idx+W-1] + 2*p_src[idx+W] + p_src[idx+W-1]);
        idx += W;
    }

    // Do bottom row
    idx = N - W + 1;
    for ( j = 1; j < W - 1; j++ )
    {
        p_dx[idx] = -(p_src[idx-W-1] + 2*p_src[idx-1] + p_src[idx-W-1]) +
                     (p_src[idx-W+1] + 2*p_src[idx+1] + p_src[idx-W+1]);
        p_dy[idx] = 0;
        idx++;
    }

    // Do left column
    idx = W;
    for ( i = 1; i < H - 1; i++ )
    {
        p_dx[idx] = 0;
        p_dy[idx] = -(p_src[idx-W+1] + 2*p_src[idx-W] + p_src[idx-W+1]) +
                     (p_src[idx+W+1] + 2*p_src[idx+W] + p_src[idx+W+1]);
        idx += W;
    }

    // Do Inner area
#if CV_SIMD128
    // Characters in variable names have the following meanings:
    // u: unsigned char
    // s: signed int
    //
    // [row][column]
    // m: offset -1
    // n: offset  0
    // p: offset  1
    // Example: umn is offset -1 in row and offset 0 in column
    v_uint8x16 v_umm, v_umn, v_ump,
               v_unm, v_unn, v_unp,
               v_upm, v_upn, v_upp;
    v_uint16x8 v_umm1, v_umm2, v_umn1, v_umn2, v_ump1, v_ump2,
               v_unm1, v_unm2, v_unn1, v_unn2, v_unp1, v_unp2,
               v_upm1, v_upm2, v_upn1, v_upn2, v_upp1, v_upp2;
    v_int16x8 v_smm1, v_smm2, v_smn1, v_smn2, v_smp1, v_smp2,
              v_snm1, v_snm2, v_snn1, v_snn2, v_snp1, v_snp2,
              v_spm1, v_spm2, v_spn1, v_spn2, v_spp1, v_spp2,
              v_two = v_setall_s16(2),
              v_sdx1, v_sdx2, v_sdy1, v_sdy2;

    // Go through 16-column chunks at a time
    for ( j = 1; j < W - 1 - 15; j += 16 )
    {
        // Load top two rows for 3x3 Sobel filter
        idx = W + j;
        v_umm = v_load(&p_src[idx - W - 1]);
        v_umn = v_load(&p_src[idx - W]);
        v_ump = v_load(&p_src[idx - W + 1]);
        v_unm = v_load(&p_src[idx - 1]);
        v_unn = v_load(&p_src[idx]);
        v_unp = v_load(&p_src[idx + 1]);

        // Expand to uint
        v_expand(v_umm, v_umm1, v_umm2);
        v_expand(v_umn, v_umn1, v_umn2);
        v_expand(v_ump, v_ump1, v_ump2);
        v_expand(v_unm, v_unm1, v_unm2);
        v_expand(v_unn, v_unn1, v_unn2);
        v_expand(v_unp, v_unp1, v_unp2);

        // Convert to int
        v_smm1 = v_reinterpret_as_s16(v_umm1);
        v_smm2 = v_reinterpret_as_s16(v_umm2);
        v_smn1 = v_reinterpret_as_s16(v_umn1);
        v_smn2 = v_reinterpret_as_s16(v_umn2);
        v_smp1 = v_reinterpret_as_s16(v_ump1);
        v_smp2 = v_reinterpret_as_s16(v_ump2);
        v_snm1 = v_reinterpret_as_s16(v_unm1);
        v_snm2 = v_reinterpret_as_s16(v_unm2);
        v_snn1 = v_reinterpret_as_s16(v_unn1);
        v_snn2 = v_reinterpret_as_s16(v_unn2);
        v_snp1 = v_reinterpret_as_s16(v_unp1);
        v_snp2 = v_reinterpret_as_s16(v_unp2);

        for ( i = 1; i < H - 1; i++ )
        {
            // Load last row for 3x3 Sobel filter
            idx = i*W + j;
            v_upm = v_load(&p_src[idx + W - 1]);
            v_upn = v_load(&p_src[idx + W]);
            v_upp = v_load(&p_src[idx + W + 1]);

            // Expand to uint
            v_expand(v_upm, v_upm1, v_upm2);
            v_expand(v_upn, v_upn1, v_upn2);
            v_expand(v_upp, v_upp1, v_upp2);

            // Convert to int
            v_spm1 = v_reinterpret_as_s16(v_upm1);
            v_spm2 = v_reinterpret_as_s16(v_upm2);
            v_spn1 = v_reinterpret_as_s16(v_upn1);
            v_spn2 = v_reinterpret_as_s16(v_upn2);
            v_spp1 = v_reinterpret_as_s16(v_upp1);
            v_spp2 = v_reinterpret_as_s16(v_upp2);

            // dx
            v_sdx1 = (v_smp1 - v_smm1) + v_two*(v_snp1 - v_snm1) + (v_spp1 - v_spm1);
            v_sdx2 = (v_smp2 - v_smm2) + v_two*(v_snp2 - v_snm2) + (v_spp2 - v_spm2);

            // dy
            v_sdy1 = (v_spm1 - v_smm1) + v_two*(v_spn1 - v_smn1) + (v_spp1 - v_smp1);
            v_sdy2 = (v_spm2 - v_smm2) + v_two*(v_spn2 - v_smn2) + (v_spp2 - v_smp2);

            // Store
            v_store(&p_dx[idx],   v_sdx1);
            v_store(&p_dx[idx+8], v_sdx2);
            v_store(&p_dy[idx],   v_sdy1);
            v_store(&p_dy[idx+8], v_sdy2);

            // Shift loaded rows up one
            v_smm1 = v_snm1;
            v_smm2 = v_snm2;
            v_smn1 = v_snn1;
            v_smn2 = v_snn2;
            v_smp1 = v_snp1;
            v_smp2 = v_snp2;
            v_snm1 = v_spm1;
            v_snm2 = v_spm2;
            v_snn1 = v_spn1;
            v_snn2 = v_spn2;
            v_snp1 = v_spp1;
            v_snp2 = v_spp2;
        }
    }

    // Cleanup
    int end_j = j;
    for ( i = 1; i < H - 1; i++ )
    for ( j = end_j; j < W - 1; j++ )
    {
        idx = i*W + j;
        p_dx[idx] = -(p_src[idx-W-1] + 2*p_src[idx-1] + p_src[idx+W-1]) +
                     (p_src[idx-W+1] + 2*p_src[idx+1] + p_src[idx+W+1]);
        p_dy[idx] = -(p_src[idx-W-1] + 2*p_src[idx-W] + p_src[idx-W+1]) +
                     (p_src[idx+W-1] + 2*p_src[idx+W] + p_src[idx+W+1]);
    }
#else
    for ( i = 1; i < H - 1; i++ )
    for ( j = 1; j < W - 1; j++ )
    {
        idx = i*W + j;
        p_dx[idx] = -(p_src[idx-W-1] + 2*p_src[idx-1] + p_src[idx+W-1]) +
                     (p_src[idx-W+1] + 2*p_src[idx+1] + p_src[idx+W+1]);
        p_dy[idx] = -(p_src[idx-W-1] + 2*p_src[idx-W] + p_src[idx-W+1]) +
                     (p_src[idx+W-1] + 2*p_src[idx+W] + p_src[idx+W+1]);
    }
#endif

}

}
<|endoftext|>