<commit_before>#include "clanghelper/arghelper.hpp"
#include "clanghelper/declprocessor.hpp"
#include "clanghelper/doxygen_utils.hpp"
#include "clanghelper/stdhelper/containerhelper.hpp"
#include <iostream>
#include <json/json.h>
#include <json/writer.h>

namespace {
const std::string PARAM_NAME_MAIN_ONLY = "--main-only";
const std::string PARAM_NAME_NO_FUNCS = "--no-functions";
const std::string PARAM_NAME_NO_STRUCTS = "--no-structs";
const std::string PARAM_NAME_NO_SIZES = "--no-sizes";
const std::string PARAM_NAME_HELP = "--help";
const std::string PARAM_NAME_WITH_SOURCE = "--with-source";

const std::vector<std::string> ALL_PARAMS = {
    PARAM_NAME_MAIN_ONLY, PARAM_NAME_NO_FUNCS, PARAM_NAME_NO_STRUCTS,
    PARAM_NAME_NO_SIZES,  PARAM_NAME_HELP,     PARAM_NAME_WITH_SOURCE};

template <typename T>
inline Json::Value to_json(const std::vector<T>& v);
inline Json::Value to_json(uint64_t v) { return v; }

template <typename T>
inline Json::Value to_json(const std::vector<T>& v)
{
    Json::Value ret(Json::arrayValue);
    for (const auto& e : v)
        ret.append(to_json(e));
    return ret;
}

} // namespace

struct DeclCollector {
    DeclCollector(int argc, const char** argv)
        : args(argc, argv, ALL_PARAMS), functions(Json::arrayValue),
          structs(Json::arrayValue)
    {
    }

    void operator()(const clang::Decl* decl)
    {
        using namespace vvv::helpers;
        const auto& flags = args.getCustomFlags();
        const auto& main_only = contain(flags, PARAM_NAME_MAIN_ONLY);
        const auto& need_functions = !contain(flags, PARAM_NAME_NO_FUNCS);
        const auto& need_structs = !contain(flags, PARAM_NAME_NO_STRUCTS);

        if (isSystemDecl(decl))
            return;
        if (main_only && !isInMainFile(decl))
            return;

        if (need_functions && isNonTemplateFunction(decl)) {
            const auto* func = decl->getAsFunction();
            addFunction(func);
            return;
        }
        if (need_structs && isRecord(decl)) {
            addRecord(static_cast<const clang::RecordDecl*>(decl));
            return;
        }
    }

    Json::Value MakeFunctionParams(const clang::FunctionDecl* func,
                                   const FunctionComments& docs)
    {
        auto ret = Json::Value(Json::arrayValue);
        for (const auto& param : getFunctionParams(func)) {
            const auto& name = getDeclName(param);
            Json::Value param_node;
            param_node["name"] = name;
            param_node["type"] = param->getType().getAsString();
            param_node["comment"] = docs.getParam(name);
            ret.append(std::move(param_node));
        }
        return ret;
    }

    Json::Value to_json(const clang::FunctionDecl* func)
    {
        using namespace vvv::helpers;
        const auto& flags = args.getCustomFlags();
        const auto& with_source = contain(flags, PARAM_NAME_WITH_SOURCE);

        const auto& name = getDeclName(func);
        const auto& docs = getDoxyComments(func);
        Json::Value ret;
        ret["name"] = name;
        ret["comment"] = docs.brief;
        ret["rettype"] = func->getReturnType().getAsString();
        ret["retcomment"] = docs.getReturn();

        ret["params"] = MakeFunctionParams(func, docs);
        ret["location"] = getLocation(func);

        if (with_source)
            ret["source"] = decl2str(func);
        return ret;
    }

    void addFunction(const clang::FunctionDecl* func)
    {
        functions.append(to_json(func));
    }

    void addArrayInfo(Json::Value& out, const clang::FieldDecl* decl)
    {
        using namespace clang;
        auto t = decl->getType();
        if (!t->isConstantArrayType())
            return;

        std::vector<uint64_t> arraySizeByDimensions;

        while (t->isConstantArrayType()) {
            const auto ca = (ConstantArrayType*)t->getAsArrayTypeUnsafe();
            const auto elemCount = *ca->getSize().getRawData();
            arraySizeByDimensions.push_back(elemCount);
            t = ca->getElementType();
        }

        const auto& elementTypeName = t.getAsString();

        Json::Value arraySize = ::to_json(arraySizeByDimensions);
        Json::Value array;
        array["elem_type"] = elementTypeName;
        array["size"] = std::move(arraySize);

        out["array"] = std::move(array);
    }

    void addBitfieldInfo(Json::Value& out, const clang::FieldDecl* decl)
    {
        if (!decl->isBitField())
            return;

        const auto& astctx = decl->getASTContext();
        const auto bitfieldWidth = decl->getBitWidthValue(astctx);
        out["bitfieldWidth"] = bitfieldWidth;
    }

    void addBasicSizeInfo(Json::Value& out, const clang::FieldDecl* decl)
    {
        auto type = decl->getType();
        if (!type->isBuiltinType())
            return;

        const auto& astctx = decl->getASTContext();
        out["builtin"] = astctx.getTypeSize(type);
    }

    Json::Value makeFields(const clang::RecordDecl* decl, bool with_sizes)
    {
        Json::Value ret(Json::arrayValue);
        for (const auto& f : getStructFields(decl)) {
            Json::Value field;
            field["name"] = getDeclName(f);
            field["type"] = f->getType().getAsString();
            field["comment"] = getComment(f);
            addArrayInfo(field, f);
            addBitfieldInfo(field, f);
            if (with_sizes)
                addBasicSizeInfo(field, f);
            ret.append(std::move(field));
        }
        return ret;
    }

    Json::Value to_json(const clang::RecordDecl* decl)
    {
        using namespace vvv::helpers;
        const auto& flags = args.getCustomFlags();
        const auto& with_source = contain(flags, PARAM_NAME_WITH_SOURCE);
        const auto& with_sizes = !contain(flags, PARAM_NAME_NO_SIZES);

        Json::Value ret;
        ret["name"] = getDeclName(decl);
        ret["comment"] = getComment(decl);
        ret["location"] = getLocation(decl);
        ret["fields"] = makeFields(decl, with_sizes);
        if (with_source)
            ret["source"] = decl2str(decl);
        return ret;
    }

    void addRecord(const clang::RecordDecl* decl)
    {
        structs.append(to_json(decl));
    }

    CxxToolArgs args;
    Json::Value functions;
    Json::Value structs;
};

void printHelpIfNeeded(const std::vector<std::string>& params)
{
    using namespace vvv::helpers;
    static const char* message =
        "cstructinfo usage:\n"
        "cstructinfo [options] <input files ...> [clang compiler options]\n"
        "Options:\n"
        "--main-only - do not process any included files. Process only "
        "specified\n"
        "--no-functions - exclude functions descriptions from output\n"
        "--no-structs - exclude structs descriptions from output\n"
        "--no-sizes - do not add sizeofs of primitive types to structs "
        "descriptions\n"
        "--with-source - add source field containing 'source'"
        " of struct/function\n"
        "--help - show this help\n";
    if (params.empty() || contain(params, PARAM_NAME_HELP)) {
        std::cout << message << std::endl;
        exit(EXIT_SUCCESS);
    }
    return;
}

int main(int argc, const char** argv)
{
    printHelpIfNeeded(argstoarray(argc, argv));

    auto d = DeclCollector(argc, argv);
    visit_decls(argc, argv, [&d](const clang::Decl* decl) { d(decl); },
                ALL_PARAMS);

    Json::Value result;
    result["functions"] = std::move(d.functions);
    result["structs"] = std::move(d.structs);

    Json::StreamWriterBuilder().newStreamWriter()->write(result, &std::cout);
    std::cout << std::endl;
    return 0;
}
<commit_msg>Refactor params<commit_after>#include "clanghelper/arghelper.hpp"
#include "clanghelper/declprocessor.hpp"
#include "clanghelper/doxygen_utils.hpp"
#include "clanghelper/stdhelper/containerhelper.hpp"
#include <iostream>
#include <json/json.h>
#include <json/writer.h>

namespace {
const std::string PARAM_NAME_MAIN_ONLY = "--main-only";
const std::string PARAM_NAME_NO_FUNCS = "--no-functions";
const std::string PARAM_NAME_NO_STRUCTS = "--no-structs";
const std::string PARAM_NAME_NO_SIZES = "--no-sizes";
const std::string PARAM_NAME_HELP = "--help";
const std::string PARAM_NAME_WITH_SOURCE = "--with-source";

const std::vector<std::string> ALL_PARAMS = {
    PARAM_NAME_MAIN_ONLY, PARAM_NAME_NO_FUNCS, PARAM_NAME_NO_STRUCTS,
    PARAM_NAME_NO_SIZES,  PARAM_NAME_HELP,     PARAM_NAME_WITH_SOURCE};

template <typename T>
inline Json::Value to_json(const std::vector<T>& v);
inline Json::Value to_json(uint64_t v) { return v; }

template <typename T>
inline Json::Value to_json(const std::vector<T>& v)
{
    Json::Value ret(Json::arrayValue);
    for (const auto& e : v)
        ret.append(to_json(e));
    return ret;
}

} // namespace

using vvv::helpers::contain;

struct DeclCollector {
    DeclCollector(int argc, const char** argv)
        : args(argc, argv, ALL_PARAMS), functions(Json::arrayValue),
          structs(Json::arrayValue),
          main_only(contain(args.getCustomFlags(), PARAM_NAME_MAIN_ONLY)),
          with_funcs(!contain(args.getCustomFlags(), PARAM_NAME_NO_FUNCS)),
          with_structs(!contain(args.getCustomFlags(), PARAM_NAME_NO_STRUCTS)),
          with_sizes(!contain(args.getCustomFlags(), PARAM_NAME_NO_SIZES)),
          with_source(contain(args.getCustomFlags(), PARAM_NAME_WITH_SOURCE))
    {
    }

    void operator()(const clang::Decl* decl)
    {
        using namespace vvv::helpers;

        if (isSystemDecl(decl))
            return;
        if (main_only && !isInMainFile(decl))
            return;

        if (with_funcs && isNonTemplateFunction(decl)) {
            const auto* func = decl->getAsFunction();
            addFunction(func);
            return;
        }
        if (with_structs && isRecord(decl)) {
            addRecord(static_cast<const clang::RecordDecl*>(decl));
            return;
        }
    }

    Json::Value MakeFunctionParams(const clang::FunctionDecl* func,
                                   const FunctionComments& docs)
    {
        auto ret = Json::Value(Json::arrayValue);
        for (const auto& param : getFunctionParams(func)) {
            const auto& name = getDeclName(param);
            Json::Value param_node;
            param_node["name"] = name;
            param_node["type"] = param->getType().getAsString();
            param_node["comment"] = docs.getParam(name);
            ret.append(std::move(param_node));
        }
        return ret;
    }

    Json::Value to_json(const clang::FunctionDecl* func)
    {
        const auto& name = getDeclName(func);
        const auto& docs = getDoxyComments(func);
        Json::Value ret;
        ret["name"] = name;
        ret["comment"] = docs.brief;
        ret["rettype"] = func->getReturnType().getAsString();
        ret["retcomment"] = docs.getReturn();

        ret["params"] = MakeFunctionParams(func, docs);
        ret["location"] = getLocation(func);

        if (with_source)
            ret["source"] = decl2str(func);
        return ret;
    }

    void addFunction(const clang::FunctionDecl* func)
    {
        functions.append(to_json(func));
    }

    void addArrayInfo(Json::Value& out, const clang::FieldDecl* decl)
    {
        using namespace clang;
        auto t = decl->getType();
        if (!t->isConstantArrayType())
            return;

        std::vector<uint64_t> arraySizeByDimensions;

        while (t->isConstantArrayType()) {
            const auto ca = (ConstantArrayType*)t->getAsArrayTypeUnsafe();
            const auto elemCount = *ca->getSize().getRawData();
            arraySizeByDimensions.push_back(elemCount);
            t = ca->getElementType();
        }

        const auto& elementTypeName = t.getAsString();

        Json::Value arraySize = ::to_json(arraySizeByDimensions);
        Json::Value array;
        array["elem_type"] = elementTypeName;
        array["size"] = std::move(arraySize);

        out["array"] = std::move(array);
    }

    void addBitfieldInfo(Json::Value& out, const clang::FieldDecl* decl)
    {
        if (!decl->isBitField())
            return;

        const auto& astctx = decl->getASTContext();
        const auto bitfieldWidth = decl->getBitWidthValue(astctx);
        out["bitfieldWidth"] = bitfieldWidth;
    }

    void addBasicSizeInfo(Json::Value& out, const clang::FieldDecl* decl)
    {
        auto type = decl->getType();
        if (!type->isBuiltinType())
            return;

        const auto& astctx = decl->getASTContext();
        out["builtin"] = astctx.getTypeSize(type);
    }

    Json::Value makeFields(const clang::RecordDecl* decl, bool with_sizes)
    {
        Json::Value ret(Json::arrayValue);
        for (const auto& f : getStructFields(decl)) {
            Json::Value field;
            field["name"] = getDeclName(f);
            field["type"] = f->getType().getAsString();
            field["comment"] = getComment(f);
            addArrayInfo(field, f);
            addBitfieldInfo(field, f);
            if (with_sizes)
                addBasicSizeInfo(field, f);
            ret.append(std::move(field));
        }
        return ret;
    }

    Json::Value to_json(const clang::RecordDecl* decl)
    {
        Json::Value ret;
        ret["name"] = getDeclName(decl);
        ret["comment"] = getComment(decl);
        ret["location"] = getLocation(decl);
        ret["fields"] = makeFields(decl, with_sizes);
        if (with_source)
            ret["source"] = decl2str(decl);
        return ret;
    }

    void addRecord(const clang::RecordDecl* decl)
    {
        structs.append(to_json(decl));
    }

    CxxToolArgs args;
    Json::Value functions;
    Json::Value structs;

    bool main_only = false;
    bool with_funcs = true;
    bool with_structs = true;
    bool with_sizes = true;
    bool with_source = false;
};

void printHelpIfNeeded(const std::vector<std::string>& params)
{
    using namespace vvv::helpers;
    static const char* message =
        "cstructinfo usage:\n"
        "cstructinfo [options] <input files ...> [clang compiler options]\n"
        "Options:\n"
        "--main-only - do not process any included files. Process only "
        "specified\n"
        "--no-functions - exclude functions descriptions from output\n"
        "--no-structs - exclude structs descriptions from output\n"
        "--no-sizes - do not add sizeofs of primitive types to structs "
        "descriptions\n"
        "--with-source - add source field containing 'source'"
        " of struct/function\n"
        "--help - show this help\n";
    if (params.empty() || contain(params, PARAM_NAME_HELP)) {
        std::cout << message << std::endl;
        exit(EXIT_SUCCESS);
    }
    return;
}

int main(int argc, const char** argv)
{
    printHelpIfNeeded(argstoarray(argc, argv));

    auto d = DeclCollector(argc, argv);
    visit_decls(argc, argv, [&d](const clang::Decl* decl) { d(decl); },
                ALL_PARAMS);

    Json::Value result;
    result["functions"] = std::move(d.functions);
    result["structs"] = std::move(d.structs);

    Json::StreamWriterBuilder().newStreamWriter()->write(result, &std::cout);
    std::cout << std::endl;
    return 0;
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993-2012 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// PluginUtils.h - Collection of useful utility functions for plugins

#include <iostream>
#include <fstream>
#include "bzfsAPI.h"
#include "plugin_config.h"
#include "plugin_utils.h"

/*
 * INI style configuration file parser class
 *
 * Comments start with # or ;
 * Ignores whitespace around sections, keys, and values
 * Default section if none is specified is [global]
 */

PluginConfig::PluginConfig(const std::string &filename)
{
  configFilename = filename;
  whitespace = " \t\r";
  errors = 0;

  parse();
}

std::string PluginConfig::item(const std::string &section, const std::string &key)
{
  std::string s = section,k = key;
  makelower(s);
  makelower(k);

  return sections[s][k];
}

void PluginConfig::parse(void)
{
  std::string line;
  std::string section;
  std::string key;
  std::string value;
  std::ifstream iniFile;
  size_t start, end;
  size_t equalPos;

  /*
   * Parse key,value pairs for sections out of the INI type
   * configuration file specified in 'filename'
   *
   */
  iniFile.open(configFilename.c_str(), std::ios::in);

  if (!iniFile.is_open()) {
    bz_debugMessagef(1, "PluginConfig: Can't open configuration file: %s", configFilename.c_str());
    errors++;
    return;
  }

  section = "global";

  while (!iniFile.eof()) {
    getline(iniFile, line);
    start = line.find_first_not_of(whitespace);

    /*
     * Look for comments and skip
     */
    if (line[start] == '#') {
      continue;
    }

    /*
     * Look for a section tag
     */
    if (line[start] == '[') {
      start = line.find_first_not_of(whitespace, start + 1);

      /* Check if the last non whitespace character is a close bracket */
      end = line.find_last_not_of(whitespace);
      if (line[end] == ']') {
	end = line.find_last_not_of(whitespace, end - 1);
	/* Got a section header - save it */
	section = line.substr(start, end - start + 1);
	bz_debugMessagef(4, "PluginConfig: Found section [%s]", section.c_str());
	continue;
      }
      /*
       * We either got a valid section or we have a
       * Malformed line - '[' but not matching close ']' which we ignore.
       */
      bz_debugMessagef(1, "PluginConfig: Malformed line ignored: %s", line.c_str());
      continue;
    }

    /*
     * No section tag, look for 'key = value' pairs
     *
     * Split the line into 'key = value' pairs
     */
    equalPos = line.find("=", start);

    /* If there is no '=' sign then ignore the line - treated as a comment */
    if (equalPos == std::string::npos) {
      if (line.find_first_not_of(whitespace) != std::string::npos)
	bz_debugMessagef(1, "PluginConfig: Malformed line ignored: %s", line.c_str());
      continue;
    }

    /* Extract the key */
    end = line.find_last_not_of(whitespace, equalPos - 1);
    key = line.substr(start, end - start + 1);

    /* Extract the value */
    start = line.find_first_not_of(whitespace, equalPos + 1);
    end = line.find_last_not_of(whitespace);
    if (start == std::string::npos || end == std::string::npos)
      value = "";
    else
      value = line.substr(start, end - start + 1);

    makelower(key);
    makelower(section);

    /* Save the section, key and value in the std::map for later retrieval */
    sections[section][key] = value;
    bz_debugMessagef(4, "PluginConfig: Found key [%s].%s = %s", section.c_str(), key.c_str(), value.c_str());
  }

  iniFile.close();
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>init the start, end and pos sizes so that things actually read correctly<commit_after>/* bzflag
 * Copyright (c) 1993-2012 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// PluginUtils.h - Collection of useful utility functions for plugins

#include <iostream>
#include <fstream>
#include "bzfsAPI.h"
#include "plugin_config.h"
#include "plugin_utils.h"

/*
 * INI style configuration file parser class
 *
 * Comments start with # or ;
 * Ignores whitespace around sections, keys, and values
 * Default section if none is specified is [global]
 */

PluginConfig::PluginConfig(const std::string &filename)
{
  configFilename = filename;
  whitespace = " \t\r";
  errors = 0;

  parse();
}

std::string PluginConfig::item(const std::string &section, const std::string &key)
{
  std::string s = section,k = key;
  makelower(s);
  makelower(k);

  return sections[s][k];
}

void PluginConfig::parse(void)
{
  std::string line;
  std::string section;
  std::string key;
  std::string value;
  std::ifstream iniFile;
  size_t start = 0, end = 0;
  size_t equalPos = 0;

  /*
   * Parse key,value pairs for sections out of the INI type
   * configuration file specified in 'filename'
   *
   */
  iniFile.open(configFilename.c_str(), std::ios::in);

  if (!iniFile.is_open()) {
    bz_debugMessagef(1, "PluginConfig: Can't open configuration file: %s", configFilename.c_str());
    errors++;
    return;
  }

  section = "global";

  while (!iniFile.eof()) {
    getline(iniFile, line);
    start = line.find_first_not_of(whitespace);

    /*
     * Look for comments and skip
     */
    if (line[start] == '#') {
      continue;
    }

    /*
     * Look for a section tag
     */
    if (line[start] == '[') {
      start = line.find_first_not_of(whitespace, start + 1);

      /* Check if the last non whitespace character is a close bracket */
      end = line.find_last_not_of(whitespace);
      if (line[end] == ']') {
	end = line.find_last_not_of(whitespace, end - 1);
	/* Got a section header - save it */
	section = line.substr(start, end - start + 1);
	bz_debugMessagef(4, "PluginConfig: Found section [%s]", section.c_str());
	continue;
      }
      /*
       * We either got a valid section or we have a
       * Malformed line - '[' but not matching close ']' which we ignore.
       */
      bz_debugMessagef(1, "PluginConfig: Malformed line ignored: %s", line.c_str());
      continue;
    }

    /*
     * No section tag, look for 'key = value' pairs
     *
     * Split the line into 'key = value' pairs
     */
    equalPos = line.find("=", start);

    /* If there is no '=' sign then ignore the line - treated as a comment */
    if (equalPos == std::string::npos) {
      if (line.find_first_not_of(whitespace) != std::string::npos)
	bz_debugMessagef(1, "PluginConfig: Malformed line ignored: %s", line.c_str());
      continue;
    }

    /* Extract the key */
    end = line.find_last_not_of(whitespace, equalPos - 1);
    key = line.substr(start, end - start + 1);

    /* Extract the value */
    start = line.find_first_not_of(whitespace, equalPos + 1);
    end = line.find_last_not_of(whitespace);
    if (start == std::string::npos || end == std::string::npos)
      value = "";
    else
      value = line.substr(start, end - start + 1);

    makelower(key);
    makelower(section);

    /* Save the section, key and value in the std::map for later retrieval */
    sections[section][key] = value;
    bz_debugMessagef(4, "PluginConfig: Found key [%s].%s = %s", section.c_str(), key.c_str(), value.c_str());
  }

  iniFile.close();
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>//
// Created by martin on 02/04/19.
//

#include <iostream>
#include <string>
#include <typeinfo>
#include <gtest/gtest.h>
#include <ros/package.h>
#include "ros/ros.h"
#include "std_msgs/String.h"

#include "rosplan_knowledge_base/KnowledgeBase.h"
#include "rosplan_knowledge_msgs/GetDomainNameService.h"
#include "rosplan_knowledge_msgs/GetAttributeService.h"
#include "rosplan_knowledge_msgs/KnowledgeItem.h"
#include "rosplan_knowledge_msgs/GetDomainOperatorService.h"
#include "rosplan_knowledge_msgs/DomainFormula.h"

//KnowledgeBase *knowledge_base_tester;

GTEST_TEST(KnowledgeBaseTests, Test1_domain_name) {

    ros::NodeHandle n("~");

    ros::ServiceClient client1 = n.serviceClient<rosplan_knowledge_msgs::GetDomainNameService>("/rosplan_knowledge_base/domain/name");
    rosplan_knowledge_msgs::GetDomainNameService srv;

    client1.call(srv);

    ASSERT_EQ("driverlog-simple", srv.response.domain_name);

}

GTEST_TEST(KnowledgeBaseTests, Test2_domain_functions) {

    ros::NodeHandle n("~");

    ros::ServiceClient client1 = n.serviceClient<rosplan_knowledge_msgs::GetAttributeService>("/rosplan_knowledge_base/domain/functions");
    rosplan_knowledge_msgs::GetAttributeService srv;

    client1.call(srv);

    //rosplan_knowledge_msgs::KnowledgeItem response = srv.response.attributes;

    std::cout << typeid(srv.response.attributes).name() << std::endl;

    ASSERT_EQ(1 , 0);
    //ASSERT_EQ("[]", srv.response.attributes);

}

/*
GTEST_TEST(KnowledgeBaseTests, Test3_domain_operators) {

    /*
    ros::NodeHandle n("~");

    ros::ServiceClient client1 = n.serviceClient<rosplan_knowledge_msgs::GetDomainOperatorService>("/rosplan_knowledge_base/domain/operators");
    rosplan_knowledge_msgs::GetDomainOperatorService srv;

    client1.call(srv);

    std::vector<std::string> expected_operator_names = srv.response.operators;

    std::vector<std::string> operator_names;
    knowledge_base_tester->getOperatorNames(operator_names);

    std::vector<std::string> expected_operator_names = {"goto_waypoint", "localise", "dock", "undock", \
        "wait_load_at_machine", "switch_machine_on", "wait_unload", "ditch"};

    ASSERT_EQ(operator_names , expected_operator_names);

}
*/

int main(int argc, char **argv) {

    ::testing::InitGoogleTest(&argc, argv);
    ros::init(argc, argv, "KnowledgeBaseTests");

    // knowledge_base_tester = new KnowledgeBase();

    return RUN_ALL_TESTS();
}
<commit_msg>Completed tests for all domain services<commit_after>//
// Created by martin on 02/04/19.
//

#include <iostream>
#include <string>
#include <vector>
#include <typeinfo>
#include <gtest/gtest.h>
#include <ros/package.h>
#include "ros/ros.h"
#include "std_msgs/String.h"

#include "rosplan_knowledge_base/KnowledgeBase.h"
#include "rosplan_knowledge_msgs/GetDomainNameService.h"
#include "rosplan_knowledge_msgs/GetDomainAttributeService.h"
#include "rosplan_knowledge_msgs/KnowledgeItem.h"
#include "rosplan_knowledge_msgs/GetDomainOperatorService.h"
#include "rosplan_knowledge_msgs/GetDomainOperatorDetailsService.h"
#include "rosplan_knowledge_msgs/GetDomainPredicateDetailsService.h"
#include "rosplan_knowledge_msgs/GetDomainTypeService.h"
#include "rosplan_knowledge_msgs/DomainFormula.h"

GTEST_TEST(KnowledgeBaseTests, Test1_domain_name) {

    ros::NodeHandle n("~");

    ros::ServiceClient client1 = n.serviceClient<rosplan_knowledge_msgs::GetDomainNameService>("/rosplan_knowledge_base/domain/name");
    rosplan_knowledge_msgs::GetDomainNameService srv;

    client1.call(srv);

    ASSERT_EQ("driverlog-simple", srv.response.domain_name);

}

GTEST_TEST(KnowledgeBaseTests, Test2_domain_functions) {

    ros::NodeHandle n("~");

    ros::ServiceClient client1 = n.serviceClient<rosplan_knowledge_msgs::GetDomainAttributeService>("/rosplan_knowledge_base/domain/functions");
    rosplan_knowledge_msgs::GetDomainAttributeService srv;

    client1.call(srv);

    // Amazon-domain does not contain any functions

    ASSERT_EQ(0, srv.response.items.size());

}

GTEST_TEST(KnowledgeBaseTests, Test3_domain_predicates) {

    ros::NodeHandle n("~");

    ros::ServiceClient client1 = n.serviceClient<rosplan_knowledge_msgs::GetDomainAttributeService>("/rosplan_knowledge_base/domain/predicates");
    rosplan_knowledge_msgs::GetDomainAttributeService srv;

    std::vector<std::string> expected_predicate_names = {"at", "in", "link", "path"};

    client1.call(srv);

    std::vector<std::string> actual_predicate_names;

    for (auto rit=srv.response.items.begin(); rit!=srv.response.items.end(); rit++) {
        actual_predicate_names.push_back(rit->name);
    }

    ASSERT_EQ(expected_predicate_names, actual_predicate_names);

}

GTEST_TEST(KnowledgeBaseTests, Test4_domain_operators) {

    ros::NodeHandle n("~");

    ros::ServiceClient client1 = n.serviceClient<rosplan_knowledge_msgs::GetDomainOperatorService>("/rosplan_knowledge_base/domain/operators");
    rosplan_knowledge_msgs::GetDomainOperatorService srv;

    std::vector<std::string> expected_operator_names = {"load-truck", "unload-truck", "board-truck", "get-out", "drive-truck", "walk"};

    client1.call(srv);

    std::vector<std::string> actual_operator_names;

    for (auto rit=srv.response.operators.begin(); rit!=srv.response.operators.end(); rit++) {
        actual_operator_names.push_back(rit->name);
    }

    ASSERT_EQ(expected_operator_names, actual_operator_names);

}

GTEST_TEST(KnowledgeBaseTests, Test5_domain_types){

    ros::NodeHandle n("~");

    ros::ServiceClient client1 = n.serviceClient<rosplan_knowledge_msgs::GetDomainTypeService>("/rosplan_knowledge_base/domain/types");
    rosplan_knowledge_msgs::GetDomainTypeService srv;

    std::vector<std::string> expected_type_names = {"place", "locatable", "driver", "truck", "item"};
    std::vector<std::string> expected_super_type_names = {"object", "object", "locatable", "locatable", "locatable"};

    client1.call(srv);

    std::vector<std::string> actual_type_names = srv.response.types;
    std::vector<std::string> actual_super_type_names = srv.response.super_types;

    ASSERT_EQ(expected_type_names, actual_type_names);
    ASSERT_EQ(expected_super_type_names, actual_super_type_names);

}

GTEST_TEST(KnowledgeBaseTests, Test6_domain_operator_details_load_truck) {

    ros::NodeHandle n("~");

    ros::ServiceClient client1 = n.serviceClient<rosplan_knowledge_msgs::GetDomainOperatorDetailsService>("/rosplan_knowledge_base/domain/operator_details");
    rosplan_knowledge_msgs::GetDomainOperatorDetailsService srv;

    srv.request.name = "load-truck";

    client1.call(srv);

    std::string detailed_operator_name = srv.response.op.formula.name;

    ASSERT_EQ(srv.request.name, detailed_operator_name);

}

GTEST_TEST(KnowledgeBaseTests, Test7_domain_predicate_details_path) {

    ros::NodeHandle n("~");

    ros::ServiceClient client1 = n.serviceClient<rosplan_knowledge_msgs::GetDomainPredicateDetailsService>("/rosplan_knowledge_base/domain/predicate_details");
    rosplan_knowledge_msgs::GetDomainPredicateDetailsService srv;

    srv.request.name = "path";

    client1.call(srv);

    std::string detailed_predicate_name = srv.response.predicate.name;

    ASSERT_EQ(srv.request.name, detailed_predicate_name);

}

// for report: test more thoroughly functions, predicates, operators. Deeper testing with operator_details and predicate_deatails. Update picture, missing service: predicate_details.

int main(int argc, char **argv) {

    ::testing::InitGoogleTest(&argc, argv);
    ros::init(argc, argv, "KnowledgeBaseTests");

    return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include "AutonomousGroup2.h"

AutonomousGroup2::AutonomousGroup2()
{
	//Goal: Pick up both bins on step with moose, drive back while setting them down
	//Antlers move up, and fit in the auton zone somehow, either by turning or activating arms.
	m_cAntlerMoose1 = new AutonAntlerMoose();
	m_cMooseLifter1 = new AutonMooseLifter();
	m_cMooseLifter2 = new AutonMooseLifter();
	m_cAutonDrive1 = new AutonDriveStraight();
	m_cAutonDrive2 = new AutonDriveStraight();
	m_cAutonDrive3 = new AutonDriveStraight();
	m_cAutonDumb1 = new AutonDumbDrive();
	m_cAutonTurner = new AutonTurn();
	m_cAutonIntakeArms = new AutonIntakeArms();

	AddSequential(m_cAutonDrive1);		//Drive backwards
	AddSequential(m_cAutonDumb1);		//Creep backwards slowly to ensure level with step
	AddSequential(m_cMooseLifter1);		//Lift up both middle bins with moose
	AddParallel(m_cMooseLifter2);		//While the moose is lowering, setting the bins down
	AddSequential(m_cAutonDrive2);		//Drive forwards to the auton zone
	AddSequential(m_cAntlerMoose1);		//Retract antlers up
	AddSequential(m_cAutonDrive3);		//Drive back a bit into the auton zone
	AddSequential(m_cAutonIntakeArms);	//Extend intake arms to fit in auton zone
	//AddSequential(m_cAutonTurner);	//Turn to fit in auton zone
}

AutonomousGroup2::~AutonomousGroup2()
{
	delete m_cAutonDrive1;
	delete m_cAutonDrive2;
	delete m_cAutonDrive3;
	delete m_cAutonDumb1;
	delete m_cAntlerMoose1;
	delete m_cMooseLifter1;
	delete m_cMooseLifter2;
	delete m_cAutonIntakeArms;
	delete m_cAutonTurner;
}

// Called just before this Command runs the first time
void AutonomousGroup2::Initialize()
{
	// Will change values once robot speed and positioning is known.
		//Drive
	m_cAutonDrive1->SetGoal(
			Preferences::GetInstance()->GetDouble("Auto-Distance-Step",-53),
			Preferences::GetInstance()->GetDouble("Auto-Tolerance-Step",1.5),
			Preferences::GetInstance()->GetDouble("Auto-Speed-Step",0.90),
			Preferences::GetInstance()->GetDouble("Auto-Timeout-Step",3) );
	m_cAutonDrive2->SetGoal(
			Preferences::GetInstance()->GetDouble("Auto-Distance-Zone",164),
			Preferences::GetInstance()->GetDouble("Auto-Tolerance-Zone",1.5),
			Preferences::GetInstance()->GetDouble("Auto-Speed-Zone",0.65),
			Preferences::GetInstance()->GetDouble("Auto-Timeout-Zone",7) );
	m_cAutonDrive3->SetGoal(
			Preferences::GetInstance()->GetDouble("Auto-Distance-Self",-40),
			Preferences::GetInstance()->GetDouble("Auto-Tolerance-Self",1.5),
			Preferences::GetInstance()->GetDouble("Auto-Speed-Self",0.75),
			Preferences::GetInstance()->GetDouble("Auto-Timeout-Self",4) );

		//Dumb Drive
	m_cAutonDumb1->SetGoal(
			Preferences::GetInstance()->GetDouble("Auto-Dumb-Speed", 0.55),
			Preferences::GetInstance()->GetDouble("Auto-Dumb-Time", 0.2));

		//Moose Lifter
	m_cMooseLifter1->SetGoal(0,
			Preferences::GetInstance()->GetDouble("Auto-MooseUp-Time", 1.0),
			true);
	m_cMooseLifter2->SetGoal(
			Preferences::GetInstance()->GetDouble("Auto-MooseDrop",140),
			Preferences::GetInstance()->GetDouble("Auto-MooseDown-Time", 2.0),
			false);

		//Antler
	m_cAntlerMoose1->SetGoal(Preferences::GetInstance()->GetDouble("Auto-Antlers-Time",1.5));

		//Turn to fit within the Auto Zone
	m_cAutonTurner->SetGoal(90, Preferences::GetInstance()->GetDouble("Auto-Turn-Threshold",2.5), 2);

		//Activate Intake Arms to fit within the Auto Zone
	m_cAutonIntakeArms->SetGoal(Preferences::GetInstance()->GetDouble("Auto-Intake-Arms-Time",15), true);

	CommandBase::antlerMoose->ControlLeftAntler(true);
	CommandBase::antlerMoose->ControlRightAntler(true);
	CommandBase::mooseLifter->MoveMooseLock(false);
}

// Called repeatedly when this Command is scheduled to run
void AutonomousGroup2::Execute()
{
}

// Make this return true when this Command no longer needs to run execute()
bool AutonomousGroup2::IsFinished()
{
	return false;
}

// Called once after isFinished returns true
void AutonomousGroup2::End()
{

}

// Called when another command which requires one or more of the same
// subsystems is scheduled to run
void AutonomousGroup2::Interrupted()
{
	End();
}
<commit_msg>Moose approach speed decreased<commit_after>#include "AutonomousGroup2.h"

AutonomousGroup2::AutonomousGroup2()
{
	//Goal: Pick up both bins on step with moose, drive back while setting them down
	//Antlers move up, and fit in the auton zone somehow, either by turning or activating arms.
	m_cAntlerMoose1 = new AutonAntlerMoose();
	m_cMooseLifter1 = new AutonMooseLifter();
	m_cMooseLifter2 = new AutonMooseLifter();
	m_cAutonDrive1 = new AutonDriveStraight();
	m_cAutonDrive2 = new AutonDriveStraight();
	m_cAutonDrive3 = new AutonDriveStraight();
	m_cAutonDumb1 = new AutonDumbDrive();
	m_cAutonTurner = new AutonTurn();
	m_cAutonIntakeArms = new AutonIntakeArms();

	AddSequential(m_cAutonDrive1);		//Drive backwards
	AddSequential(m_cAutonDumb1);		//Creep backwards slowly to ensure level with step
	AddSequential(m_cMooseLifter1);		//Lift up both middle bins with moose
	AddParallel(m_cMooseLifter2);		//While the moose is lowering, setting the bins down
	AddSequential(m_cAutonDrive2);		//Drive forwards to the auton zone
	AddSequential(m_cAntlerMoose1);		//Retract antlers up
	AddSequential(m_cAutonDrive3);		//Drive back a bit into the auton zone
	AddSequential(m_cAutonIntakeArms);	//Extend intake arms to fit in auton zone
	//AddSequential(m_cAutonTurner);	//Turn to fit in auton zone
}

AutonomousGroup2::~AutonomousGroup2()
{
	delete m_cAutonDrive1;
	delete m_cAutonDrive2;
	delete m_cAutonDrive3;
	delete m_cAutonDumb1;
	delete m_cAntlerMoose1;
	delete m_cMooseLifter1;
	delete m_cMooseLifter2;
	delete m_cAutonIntakeArms;
	delete m_cAutonTurner;
}

// Called just before this Command runs the first time
void AutonomousGroup2::Initialize()
{
	// Will change values once robot speed and positioning is known.
		//Drive
	m_cAutonDrive1->SetGoal(
			Preferences::GetInstance()->GetDouble("Auto-Distance-Step",-53),
			Preferences::GetInstance()->GetDouble("Auto-Tolerance-Step",1.5),
			Preferences::GetInstance()->GetDouble("Auto-Speed-Step",0.75),
			Preferences::GetInstance()->GetDouble("Auto-Timeout-Step",3) );
	m_cAutonDrive2->SetGoal(
			Preferences::GetInstance()->GetDouble("Auto-Distance-Zone",164),
			Preferences::GetInstance()->GetDouble("Auto-Tolerance-Zone",1.5),
			Preferences::GetInstance()->GetDouble("Auto-Speed-Zone",0.65),
			Preferences::GetInstance()->GetDouble("Auto-Timeout-Zone",7) );
	m_cAutonDrive3->SetGoal(
			Preferences::GetInstance()->GetDouble("Auto-Distance-Self",-40),
			Preferences::GetInstance()->GetDouble("Auto-Tolerance-Self",1.5),
			Preferences::GetInstance()->GetDouble("Auto-Speed-Self",0.75),
			Preferences::GetInstance()->GetDouble("Auto-Timeout-Self",4) );

		//Dumb Drive
	m_cAutonDumb1->SetGoal(
			Preferences::GetInstance()->GetDouble("Auto-Dumb-Speed", 0.55),
			Preferences::GetInstance()->GetDouble("Auto-Dumb-Time", 0.2));

		//Moose Lifter
	m_cMooseLifter1->SetGoal(0,
			Preferences::GetInstance()->GetDouble("Auto-MooseUp-Time", 1.0),
			true);
	m_cMooseLifter2->SetGoal(
			Preferences::GetInstance()->GetDouble("Auto-MooseDrop",140),
			Preferences::GetInstance()->GetDouble("Auto-MooseDown-Time", 2.0),
			false);

		//Antler
	m_cAntlerMoose1->SetGoal(Preferences::GetInstance()->GetDouble("Auto-Antlers-Time",1.5));

		//Turn to fit within the Auto Zone
	m_cAutonTurner->SetGoal(90, Preferences::GetInstance()->GetDouble("Auto-Turn-Threshold",2.5), 2);

		//Activate Intake Arms to fit within the Auto Zone
	m_cAutonIntakeArms->SetGoal(Preferences::GetInstance()->GetDouble("Auto-Intake-Arms-Time",15), true);

	CommandBase::antlerMoose->ControlLeftAntler(true);
	CommandBase::antlerMoose->ControlRightAntler(true);
	CommandBase::mooseLifter->MoveMooseLock(false);
}

// Called repeatedly when this Command is scheduled to run
void AutonomousGroup2::Execute()
{
}

// Make this return true when this Command no longer needs to run execute()
bool AutonomousGroup2::IsFinished()
{
	return false;
}

// Called once after isFinished returns true
void AutonomousGroup2::End()
{

}

// Called when another command which requires one or more of the same
// subsystems is scheduled to run
void AutonomousGroup2::Interrupted()
{
	End();
}
<|endoftext|>


<commit_before>#include "GraphicsService.hpp"

#include "Global.hpp"
#include "TimeService.hpp"
#include "Render.hpp"
#include "Texture2D.hpp"
#include "TextureMappedFont.hpp"
#include "Log.hpp"

namespace Core
{
    GraphicsService::GraphicsService() :
        mDisplay(EGL_NO_DISPLAY),
        mSurface(EGL_NO_CONTEXT),
        mContext(EGL_NO_SURFACE)
    {
    	LOGI("Creating GraphicsService.");
    }

    Status GraphicsService::Start()
    {
    	int mWidth(0),mHeight(0);

    	LOGI("Starting GraphicsService.");

        EGLint lFormat, lNumConfigs, lErrorResult;
        EGLConfig lConfig;
        // Defines display requirements. 16bits mode here.
        const EGLint lAttributes[] =
        	{
        		EGL_RENDERABLE_TYPE, EGL_WINDOW_BIT,
        		EGL_RED_SIZE, 8,
        		EGL_GREEN_SIZE, 8,
        		EGL_BLUE_SIZE, 8,
        		EGL_DEPTH_SIZE, 24,
        		EGL_NONE
        	};
        const EGLint lContextAttrib[] =
		{
			EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE
		};

        // Retrieves a display connection and initializes it.
        LOGD("Connecting to the display.");
        mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
        if (mDisplay == EGL_NO_DISPLAY)
        {
        	LOGE("EGL_NO_DISPLAY");
        	goto ERROR;
        }
        if (!eglInitialize(mDisplay, NULL, NULL))
        {
        	LOGE("Unable to initialize display");
        	goto ERROR;
        }

        // Selects the first OpenGL configuration found.
        LOGD("Selecting a display config.");
        if(!eglChooseConfig(mDisplay, lAttributes, &lConfig, 1, &lNumConfigs) || (lNumConfigs <= 0))
        {
        	LOGE("Unable to select display configuration");
        	goto ERROR;
        }

        // Reconfigures the Android window with the EGL format.
        LOGD("Configuring window format.");
        if (!eglGetConfigAttrib(mDisplay, lConfig, EGL_NATIVE_VISUAL_ID, &lFormat))
        {
        	LOGE("Unable to configure window format");
        	goto ERROR;
        }
        ANativeWindow_setBuffersGeometry(Global::pAndroidApp->window, 0, 0, lFormat);
        // Creates the display surface.
        LOGD("Initializing the display.");
        mSurface = eglCreateWindowSurface(mDisplay, lConfig, Global::pAndroidApp->window, NULL);
        if (mSurface == EGL_NO_SURFACE)
        {
        	LOGE("EGL_NO_SURFACE");
        	goto ERROR;
        }
        mContext = eglCreateContext(mDisplay, lConfig, EGL_NO_CONTEXT, lContextAttrib);
        if (mContext == EGL_NO_CONTEXT)
        {
        	LOGE("EGL_NO_CONTEXT");
        	goto ERROR;
        }

        // Activates the display surface.
        LOGD("Activating the display.");
        if (!eglMakeCurrent(mDisplay, mSurface, mSurface, mContext)
         || !eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth)
         || !eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight)
         || (mWidth <= 0) || (mHeight <= 0))
        {
        	LOGE("Unable to activate display");
        	goto ERROR;
        }

        // Displays information about OpenGL.
        LOGI("Starting GraphicsService");
        LOGI("Version  : %s", glGetString(GL_VERSION));
        LOGI("Vendor   : %s", glGetString(GL_VENDOR));
        LOGI("Renderer : %s", glGetString(GL_RENDERER));
        LOGI("Viewport : %d x %d", mWidth, mHeight);

		Setup(mWidth,mHeight);
		return STATUS_OK;

    ERROR:
    	LOGE("Error while starting GraphicsService");
        Stop();
        return STATUS_KO;
    }

    void GraphicsService::Stop()
    {
    	LOGI("GraphicsService::Stop");

    	UnloadResources();

    	Render::DisableOrthoMode();

        // Destroys OpenGL context.
        if (mDisplay != EGL_NO_DISPLAY)
        {
            eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
            if (mContext != EGL_NO_CONTEXT)
            {
                eglDestroyContext(mDisplay, mContext);
                mContext = EGL_NO_CONTEXT;
            }
            if (mSurface != EGL_NO_SURFACE)
            {
                eglDestroySurface(mDisplay, mSurface);
                mSurface = EGL_NO_SURFACE;
            }
            eglTerminate(mDisplay);
            mDisplay = EGL_NO_DISPLAY;
        }
    }

    void GraphicsService::Setup(int width, int height)
    {
    	Render::Init();
		Render::SetScreenSize(width,height);
		Render::SetOrthoMode();
		Render::EnableOrthoMode();

		LoadResources();
    }

    void GraphicsService::Update()
    {
        float lTimeStep = Global::pContext->pTimeService->Elapsed();
    }

    Status GraphicsService::Render()
    {
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		SpriteBatcher::Flush();

		if(eglSwapBuffers(mDisplay, mSurface)!=EGL_TRUE)
		{
			LOGE("Error %d swapping buffers.",eglGetError());
			return STATUS_KO;
		}

		return STATUS_OK;
    }

    Status GraphicsService::LoadResources()
    {
    	InitVertexPrograms();

    	Global::pFont=new TextureMappedFont;
    	Global::pFont->Load("@Font.tga");

    	return STATUS_OK;
    }

    Status GraphicsService::UnloadResources()
    {
    	delete Global::pFont;

    	DeleteVertexPrograms();

    	return STATUS_OK;
    }
}
<commit_msg>Graphics Service now update and render Particle engine<commit_after>#include "GraphicsService.hpp"

#include "Global.hpp"
#include "TimeService.hpp"
#include "Render.hpp"
#include "Texture2D.hpp"
#include "TextureMappedFont.hpp"
#include "Log.hpp"
#include "Particles.hpp"

namespace Core
{
    GraphicsService::GraphicsService() :
        mDisplay(EGL_NO_DISPLAY),
        mSurface(EGL_NO_CONTEXT),
        mContext(EGL_NO_SURFACE)
    {
    	LOGI("Creating GraphicsService.");
    }

    Status GraphicsService::Start()
    {
    	int mWidth(0),mHeight(0);

    	LOGI("Starting GraphicsService.");

        EGLint lFormat, lNumConfigs, lErrorResult;
        EGLConfig lConfig;
        // Defines display requirements. 16bits mode here.
        const EGLint lAttributes[] =
        	{
        		EGL_RENDERABLE_TYPE, EGL_WINDOW_BIT,
        		EGL_RED_SIZE, 8,
        		EGL_GREEN_SIZE, 8,
        		EGL_BLUE_SIZE, 8,
        		EGL_DEPTH_SIZE, 24,
        		EGL_NONE
        	};
        const EGLint lContextAttrib[] =
		{
			EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE
		};

        // Retrieves a display connection and initializes it.
        LOGD("Connecting to the display.");
        mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
        if (mDisplay == EGL_NO_DISPLAY)
        {
        	LOGE("EGL_NO_DISPLAY");
        	goto ERROR;
        }
        if (!eglInitialize(mDisplay, NULL, NULL))
        {
        	LOGE("Unable to initialize display");
        	goto ERROR;
        }

        // Selects the first OpenGL configuration found.
        LOGD("Selecting a display config.");
        if(!eglChooseConfig(mDisplay, lAttributes, &lConfig, 1, &lNumConfigs) || (lNumConfigs <= 0))
        {
        	LOGE("Unable to select display configuration");
        	goto ERROR;
        }

        // Reconfigures the Android window with the EGL format.
        LOGD("Configuring window format.");
        if (!eglGetConfigAttrib(mDisplay, lConfig, EGL_NATIVE_VISUAL_ID, &lFormat))
        {
        	LOGE("Unable to configure window format");
        	goto ERROR;
        }
        ANativeWindow_setBuffersGeometry(Global::pAndroidApp->window, 0, 0, lFormat);
        // Creates the display surface.
        LOGD("Initializing the display.");
        mSurface = eglCreateWindowSurface(mDisplay, lConfig, Global::pAndroidApp->window, NULL);
        if (mSurface == EGL_NO_SURFACE)
        {
        	LOGE("EGL_NO_SURFACE");
        	goto ERROR;
        }
        mContext = eglCreateContext(mDisplay, lConfig, EGL_NO_CONTEXT, lContextAttrib);
        if (mContext == EGL_NO_CONTEXT)
        {
        	LOGE("EGL_NO_CONTEXT");
        	goto ERROR;
        }

        // Activates the display surface.
        LOGD("Activating the display.");
        if (!eglMakeCurrent(mDisplay, mSurface, mSurface, mContext)
         || !eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth)
         || !eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight)
         || (mWidth <= 0) || (mHeight <= 0))
        {
        	LOGE("Unable to activate display");
        	goto ERROR;
        }

        // Displays information about OpenGL.
        LOGI("Starting GraphicsService");
        LOGI("Version  : %s", glGetString(GL_VERSION));
        LOGI("Vendor   : %s", glGetString(GL_VENDOR));
        LOGI("Renderer : %s", glGetString(GL_RENDERER));
        LOGI("Viewport : %d x %d", mWidth, mHeight);

		Setup(mWidth,mHeight);
		return STATUS_OK;

    ERROR:
    	LOGE("Error while starting GraphicsService");
        Stop();
        return STATUS_KO;
    }

    void GraphicsService::Stop()
    {
    	LOGI("GraphicsService::Stop");

    	UnloadResources();

    	Render::DisableOrthoMode();

        // Destroys OpenGL context.
        if (mDisplay != EGL_NO_DISPLAY)
        {
            eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
            if (mContext != EGL_NO_CONTEXT)
            {
                eglDestroyContext(mDisplay, mContext);
                mContext = EGL_NO_CONTEXT;
            }
            if (mSurface != EGL_NO_SURFACE)
            {
                eglDestroySurface(mDisplay, mSurface);
                mSurface = EGL_NO_SURFACE;
            }
            eglTerminate(mDisplay);
            mDisplay = EGL_NO_DISPLAY;
        }
    }

    void GraphicsService::Setup(int width, int height)
    {
    	Render::Init();
		Render::SetScreenSize(width,height);
		Render::SetOrthoMode();
		Render::EnableOrthoMode();

		LoadResources();
    }

    void GraphicsService::Update()
    {
        float lTimeStep = Global::pContext->pTimeService->Elapsed();

        ParticleEmitter::UpdateAll(lTimeStep);
        Particle::UpdateAll(lTimeStep);
    }

    Status GraphicsService::Render()
    {
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    	Particle::RenderAll();
		SpriteBatcher::Flush();

		if(eglSwapBuffers(mDisplay, mSurface)!=EGL_TRUE)
		{
			LOGE("Error %d swapping buffers.",eglGetError());
			return STATUS_KO;
		}

		return STATUS_OK;
    }

    Status GraphicsService::LoadResources()
    {
    	InitVertexPrograms();

    	Global::pFont=new TextureMappedFont;
    	Global::pFont->Load("@Font.tga");

    	return STATUS_OK;
    }

    Status GraphicsService::UnloadResources()
    {
    	delete Global::pFont;

    	DeleteVertexPrograms();

    	return STATUS_OK;
    }
}
<|endoftext|>


<commit_before>#include <netdb.h>
#include <unistd.h>
#include <sys/fcntl.h>

#include "client.h"
#include "duckchat.h"

// Variables
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
int client_socket;
struct addrinfo *server_info;
char *channel;

// Prints an error message and exits the program.
void Error(const char *msg) {
  std::cerr << msg << std::endl;
  exit(1);
}

// Connects to the server at a the given port.
void Connect(char *domain, const char *port) {
  std::cout << "Connecting to " << domain << std::endl;

  struct addrinfo hints;
  struct addrinfo *server_info_tmp;
  int status;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_protocol = 0;

  if ((status = getaddrinfo(domain, port, &hints, &server_info_tmp)) != 0) {
    std::cerr << "client: unable to resolve address: " << gai_strerror(status) << std::endl;
    exit(1);
  }

  // getaddrinfo() returns a list of address structures into server_info_tmp.
  // Try each address until we successfully connect().
  // If socket() (or connect()) fails, close the socket and try the next address.

  for (server_info = server_info_tmp; server_info != NULL; server_info = server_info->ai_next) {
    if ((client_socket = socket(server_info->ai_family, server_info->ai_socktype, server_info->ai_protocol)) < 0) {
      continue;
    }
    if (connect(client_socket, server_info->ai_addr, server_info->ai_addrlen) != -1) {
      fcntl(client_socket, F_SETFL, O_NONBLOCK);
      break; // Success
    }
    close(client_socket);
  }

  if (server_info == NULL) {
    Error("client: all sockets failed to connect");
  }
}

// Sends a message to all users in on the active channel.
int RequestSay(const char *message) {
  struct request_say say;
  memset(&say, 0, sizeof(say));
  say.req_type = REQ_SAY;
  strncpy(say.req_text, message, SAY_MAX);
  strncpy(say.req_channel, channel, CHANNEL_MAX);

  if (sendto(client_socket, &say, sizeof(say), 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to send message\n");
  }

  return 0;
}

// Sends login requests to the server.
int RequestLogin(char *username) {
  struct request_login login;
  memset(&login, 0, sizeof(login));
  login.req_type = REQ_LOGIN;
  strncpy(login.req_username, username, USERNAME_MAX);

  size_t message_size = sizeof(struct request_login);

  if (sendto(client_socket, &login, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request login\n");
  }

  return 0;
}

// Sends logout requests to the server.
int RequestLogout() {
  struct request_logout logout;
  memset((char *) &logout, 0, sizeof(logout));
  logout.req_type = REQ_LOGOUT;

  size_t message_size = sizeof(struct request_logout);

  if (sendto(client_socket, &logout, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request logout\n");
  }

  return 0;
}

// Sends join requests to the server.
int RequestJoin(char *channel) {
  struct request_join join;
  memset((char *) &join, 0, sizeof(join));
  join.req_type = REQ_JOIN;
  strncpy(join.req_channel, channel, CHANNEL_MAX);

  size_t message_size = sizeof(struct request_join);

  if (sendto(client_socket, &join, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request join\n");
  }

  return 0;
}

// Splits strings around spaces.
std::vector<std::string> StringSplit(std::string input) {
  std::istringstream iss(input);
  std::vector<std::string> result{std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};

  return result;
}

// Splits strings around spaces.
std::vector<std::string> SplitString(char *input, char delimiter) {
  std::vector<std::string> result;
  std::string word = "";

  size_t input_size = strlen(input);
  for (size_t i = 0; i < input_size; i++) {
    if (input[i] != delimiter) {
      word += input[i];
    } else {
      result.push_back(word);
      word = "";
    }
  }
  result.push_back(word);

  return result;
}

void StripChar(char *input, char c) {
  size_t size = strlen(input);
  for (size_t i = 0; i < size; i++) {
    if (input[i] == c) {
      input[i] = '\0';
    }
  }
}

// Processes the input string to decide what type of command it is.
bool ProcessInput(std::string input) {
  std::vector<std::string> inputs = StringSplit(input);
  bool result = true;

  if (inputs[0] == "/exit") {
    RequestLogout();
    result = false;
  } else if (inputs[0] == "/list") {

  } else if (inputs[0] == "/join") {

  } else if (inputs[0] == "/leave") {

  } else if (inputs[0] == "/who") {

  } else if (inputs[0] == "/switch") {

  } else {
    std::cout << "\n*Unknown command" << std::endl;
  }

  return result;
}

int main(int argc, char *argv[]) {
  char *domain;
  char *port_str;
  int port_num;
  char *username;
//  std::string input;

//  struct timeval timeout;
  fd_set read_set;
//  int file_desc = 0;
  int result;
  char receive_buffer[kBufferSize];
  memset(&receive_buffer, 0, kBufferSize);

  char stdin_buffer[kBufferSize];
  memset(&stdin_buffer, 0, kBufferSize);

  if (argc < 4) {
    Error("usage: client [server name] [port] [username]");
  }

  domain = argv[1];
  port_str = argv[2];
  port_num = atoi(argv[2]);
  username = argv[3];

  if (strlen(domain) > UNIX_PATH_MAX) {
    Error("client: server name must be less than 108 characters");
  }

  if (port_num < 0 || port_num > 65535) {
    Error("client: port number must be between 0 and 65535");
  }

  if (strlen(username) > USERNAME_MAX) {
    Error("client: username must be less than 32 characters");
  }

  Connect(domain, port_str);

  RequestLogin(username);

  channel = (char *) "Common";
  RequestJoin(channel);

  // TODO handle response from send

  std::cout << ">" << std::flush;

  std::string tmp;

  while (1) {
    FD_ZERO(&read_set);
    FD_SET(client_socket, &read_set);
    FD_SET(STDIN_FILENO, &read_set);

    if ((result = select(client_socket + 1, &read_set, NULL, NULL, NULL)) < 0) {
      Error("client: problem using select");
    }

    if (result > 0) {
      if (FD_ISSET(STDIN_FILENO, &read_set)) {
        int read_stdin_size = read(STDIN_FILENO, stdin_buffer, kBufferSize);

        if (read_stdin_size != 0) {
          if (stdin_buffer[0] == '/') {
            ProcessInput(stdin_buffer);
          } else {
            // Send chat messages
            StripChar(stdin_buffer, '\n');
            RequestSay(stdin_buffer);
          }
        }

        memset(&stdin_buffer, 0, kBufferSize);
      } // end of if STDIN

      if (FD_ISSET(client_socket, &read_set)) {
        // Socket has data
        int read_size = read(client_socket, receive_buffer, kBufferSize);

        if (read_size != 0) {
          // TODO capture user input, store, clean input, then print buffer, afterward replace input
          struct text message;
          memcpy(&message, receive_buffer, sizeof(struct text));
          text_t text_type = message.txt_type;

          switch (text_type) {
            case TXT_SAY:
              struct text_say say;
              memcpy(&say, receive_buffer, sizeof(struct text_say));
              std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
              std::cout << "[" << say.txt_channel << "]" << "[" << say.txt_username << "]: " << say.txt_text << std::endl;
              std::cout << ">" << stdin_buffer << std::flush;
              break;
            default:
              break;
          }
        }

        memset(&receive_buffer, 0, SAY_MAX);
      } // end of if client_socket

    } // end of if result

  } // end of while

  return 0;
}<commit_msg>print buffer manually in stdin check<commit_after>#include <netdb.h>
#include <unistd.h>
#include <sys/fcntl.h>

#include "client.h"
#include "duckchat.h"

// Variables
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
int client_socket;
struct addrinfo *server_info;
char *channel;

// Prints an error message and exits the program.
void Error(const char *msg) {
  std::cerr << msg << std::endl;
  exit(1);
}

// Connects to the server at a the given port.
void Connect(char *domain, const char *port) {
  std::cout << "Connecting to " << domain << std::endl;

  struct addrinfo hints;
  struct addrinfo *server_info_tmp;
  int status;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_protocol = 0;

  if ((status = getaddrinfo(domain, port, &hints, &server_info_tmp)) != 0) {
    std::cerr << "client: unable to resolve address: " << gai_strerror(status) << std::endl;
    exit(1);
  }

  // getaddrinfo() returns a list of address structures into server_info_tmp.
  // Try each address until we successfully connect().
  // If socket() (or connect()) fails, close the socket and try the next address.

  for (server_info = server_info_tmp; server_info != NULL; server_info = server_info->ai_next) {
    if ((client_socket = socket(server_info->ai_family, server_info->ai_socktype, server_info->ai_protocol)) < 0) {
      continue;
    }
    if (connect(client_socket, server_info->ai_addr, server_info->ai_addrlen) != -1) {
      fcntl(client_socket, F_SETFL, O_NONBLOCK);
      break; // Success
    }
    close(client_socket);
  }

  if (server_info == NULL) {
    Error("client: all sockets failed to connect");
  }
}

// Sends a message to all users in on the active channel.
int RequestSay(const char *message) {
  struct request_say say;
  memset(&say, 0, sizeof(say));
  say.req_type = REQ_SAY;
  strncpy(say.req_text, message, SAY_MAX);
  strncpy(say.req_channel, channel, CHANNEL_MAX);

  if (sendto(client_socket, &say, sizeof(say), 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to send message\n");
  }

  return 0;
}

// Sends login requests to the server.
int RequestLogin(char *username) {
  struct request_login login;
  memset(&login, 0, sizeof(login));
  login.req_type = REQ_LOGIN;
  strncpy(login.req_username, username, USERNAME_MAX);

  size_t message_size = sizeof(struct request_login);

  if (sendto(client_socket, &login, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request login\n");
  }

  return 0;
}

// Sends logout requests to the server.
int RequestLogout() {
  struct request_logout logout;
  memset((char *) &logout, 0, sizeof(logout));
  logout.req_type = REQ_LOGOUT;

  size_t message_size = sizeof(struct request_logout);

  if (sendto(client_socket, &logout, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request logout\n");
  }

  return 0;
}

// Sends join requests to the server.
int RequestJoin(char *channel) {
  struct request_join join;
  memset((char *) &join, 0, sizeof(join));
  join.req_type = REQ_JOIN;
  strncpy(join.req_channel, channel, CHANNEL_MAX);

  size_t message_size = sizeof(struct request_join);

  if (sendto(client_socket, &join, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request join\n");
  }

  return 0;
}

// Splits strings around spaces.
std::vector<std::string> StringSplit(std::string input) {
  std::istringstream iss(input);
  std::vector<std::string> result{std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};

  return result;
}

// Splits strings around spaces.
std::vector<std::string> SplitString(char *input, char delimiter) {
  std::vector<std::string> result;
  std::string word = "";

  size_t input_size = strlen(input);
  for (size_t i = 0; i < input_size; i++) {
    if (input[i] != delimiter) {
      word += input[i];
    } else {
      result.push_back(word);
      word = "";
    }
  }
  result.push_back(word);

  return result;
}

void StripChar(char *input, char c) {
  size_t size = strlen(input);
  for (size_t i = 0; i < size; i++) {
    if (input[i] == c) {
      input[i] = '\0';
    }
  }
}

// Processes the input string to decide what type of command it is.
bool ProcessInput(std::string input) {
  std::vector<std::string> inputs = StringSplit(input);
  bool result = true;

  if (inputs[0] == "/exit") {
    RequestLogout();
    result = false;
  } else if (inputs[0] == "/list") {

  } else if (inputs[0] == "/join") {

  } else if (inputs[0] == "/leave") {

  } else if (inputs[0] == "/who") {

  } else if (inputs[0] == "/switch") {

  } else {
    std::cout << "\n*Unknown command" << std::endl;
  }

  return result;
}

int main(int argc, char *argv[]) {
  char *domain;
  char *port_str;
  int port_num;
  char *username;
//  std::string input;

//  struct timeval timeout;
  fd_set read_set;
//  int file_desc = 0;
  int result;
  char receive_buffer[kBufferSize];
  memset(&receive_buffer, 0, kBufferSize);

  char stdin_buffer[kBufferSize];
  memset(&stdin_buffer, 0, kBufferSize);

  if (argc < 4) {
    Error("usage: client [server name] [port] [username]");
  }

  domain = argv[1];
  port_str = argv[2];
  port_num = atoi(argv[2]);
  username = argv[3];

  if (strlen(domain) > UNIX_PATH_MAX) {
    Error("client: server name must be less than 108 characters");
  }

  if (port_num < 0 || port_num > 65535) {
    Error("client: port number must be between 0 and 65535");
  }

  if (strlen(username) > USERNAME_MAX) {
    Error("client: username must be less than 32 characters");
  }

  Connect(domain, port_str);

  RequestLogin(username);

  channel = (char *) "Common";
  RequestJoin(channel);

  // TODO handle response from send

  std::cout << ">" << std::flush;

  std::string tmp;

  while (1) {
    FD_ZERO(&read_set);
    FD_SET(client_socket, &read_set);
    FD_SET(STDIN_FILENO, &read_set);

    if ((result = select(client_socket + 1, &read_set, NULL, NULL, NULL)) < 0) {
      Error("client: problem using select");
    }

    if (result > 0) {
      if (FD_ISSET(STDIN_FILENO, &read_set)) {
        int read_stdin_size = read(STDIN_FILENO, stdin_buffer, kBufferSize);

        if (read_stdin_size != 0) {
          if (stdin_buffer[0] == '/') {
            ProcessInput(stdin_buffer);
          } else {
            // Send chat messages
            StripChar(stdin_buffer, '\n');
            RequestSay(stdin_buffer);
            std::cout << ">" << stdin_buffer << std::flush;
          }
        }

        memset(&stdin_buffer, 0, kBufferSize);
      } // end of if STDIN

      if (FD_ISSET(client_socket, &read_set)) {
        // Socket has data
        int read_size = read(client_socket, receive_buffer, kBufferSize);

        if (read_size != 0) {
          // TODO capture user input, store, clean input, then print buffer, afterward replace input
          struct text message;
          memcpy(&message, receive_buffer, sizeof(struct text));
          text_t text_type = message.txt_type;

          switch (text_type) {
            case TXT_SAY:
              struct text_say say;
              memcpy(&say, receive_buffer, sizeof(struct text_say));
              std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
              std::cout << "[" << say.txt_channel << "]" << "[" << say.txt_username << "]: " << say.txt_text << std::endl;
              std::cout << ">" << stdin_buffer << std::flush;
              break;
            default:
              break;
          }
        }

        memset(&receive_buffer, 0, SAY_MAX);
      } // end of if client_socket

    } // end of if result

  } // end of while

  return 0;
}<|endoftext|>


<commit_before>#pragma once

#include "vm/code_segment.hpp"

/// End of recursion (noop)
void add_code( perseus::detail::code_segment& out_code )
{
}

/**
@brief Add values to a code segment
@param out_code[in,out] code to append onto
@param head first value to append
@param tail remaining values to append
*/
template< typename Head, typename... Tail >
void add_code( perseus::detail::code_segment& out_code, Head head, Tail... tail )
{
  out_code.push< Head >( head );
  add_code( out_code, tail... );
}

template< typename... Args >
perseus::detail::code_segment create_code_segment( Args... args )
{
  perseus::detail::code_segment code;
  add_code( code, args... );
  return code;
}
<commit_msg>fixed duplicate symbols when including test/write_code_segment.hpp repeatedly<commit_after>#pragma once

#include "vm/code_segment.hpp"

/// End of recursion (noop)
static void add_code( perseus::detail::code_segment& out_code )
{
}

/**
@brief Add values to a code segment
@param out_code[in,out] code to append onto
@param head first value to append
@param tail remaining values to append
*/
template< typename Head, typename... Tail >
void add_code( perseus::detail::code_segment& out_code, Head head, Tail... tail )
{
  out_code.push< Head >( head );
  add_code( out_code, tail... );
}

template< typename... Args >
perseus::detail::code_segment create_code_segment( Args... args )
{
  perseus::detail::code_segment code;
  add_code( code, args... );
  return code;
}
<|endoftext|>


<commit_before>/*!
 * \copy
 *     Copyright (c)  2009-2013, Cisco Systems
 *     All rights reserved.
 *
 *     Redistribution and use in source and binary forms, with or without
 *     modification, are permitted provided that the following conditions
 *     are met:
 *
 *        * Redistributions of source code must retain the above copyright
 *          notice, this list of conditions and the following disclaimer.
 *
 *        * Redistributions 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.
 *
 *     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
 *     COPYRIGHT HOLDER 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.
 *
 *
 * \file	utils.c
 *
 * \brief	common tool/function utilization
 *
 * \date	03/10/2009 Created
 *
 *************************************************************************************
 */
#if defined(_WIN32)
#include <windows.h>
#include <sys/types.h>
#include <sys/timeb.h>
#ifndef _MSC_VER
#include <sys/time.h>
#endif
#else
#include <sys/time.h>
#endif

#include "utils.h"
#include "property.h"
#include "encoder_context.h"
#include "property.h"
#include "crt_util_safe_x.h"	// Safe CRT routines like utils for cross platforms

namespace WelsSVCEnc {

void WelsLogDefault (void* pCtx, const int32_t kiLevel, const str_t* kpFmtStr, va_list argv);
void WelsLogNil (void* pCtx, const int32_t kiLevel, const str_t* kpFmtStr, va_list argv);

real32_t WelsCalcPsnr (const void* kpTarPic,
                       const int32_t kiTarStride,
                       const void* kpRefPic,
                       const int32_t kiRefStride,
                       const int32_t kiWidth,
                       const int32_t kiHeight);

// to fill default routines
#ifdef ENABLE_TRACE_FILE
PWelsLogCallbackFunc wlog	= WelsLogDefault;
#else
PWelsLogCallbackFunc wlog	= WelsLogNil;
#endif

iWelsLogLevel		g_iLevelLog	= WELS_LOG_DEFAULT;	// default log iLevel
int32_t			g_iSizeLogBuf	= 1024;			// pBuffer size for each log output

/*
 *	Log output routines
 */

/*!
 * \brief	get log tag
 * \param	kiLevel		log iLevel
 * \return  tag of log iLevel
 */
static inline str_t* GetLogTag (const int32_t kiLevel, int32_t* pBit) {
  int32_t iShift	= 0;
  int32_t iVal		= 0;
  bool_t	bFound	= false;

  if (kiLevel <= 0 || kiLevel > (1 << (WELS_LOG_LEVEL_COUNT - 1)) || NULL == pBit)
    return NULL;

  for (;;) {
    if (iShift >= WELS_LOG_LEVEL_COUNT)
      break;
    iVal	= (1 << iShift);
    if (iVal == kiLevel) {
      bFound	= true;
      break;
    }
    ++ iShift;
  }

  if (bFound) {
    *pBit	= iShift;
    return (str_t*)g_sWelsLogTags[iShift];
  }
  return NULL;
}

/*!
 *************************************************************************************
 * \brief	System trace log output in Wels
 *
 * \param	pCtx	instance pointer
 * \param	kiLevel	log iLevel ( WELS_LOG_QUIET, ERROR, WARNING, INFO, DEBUG )
 * \param	kpFmtStr	formated string to mount
 * \param 	argv	pData string argument
 *
 * \return	NONE
 *
 * \note	N/A
 *************************************************************************************
 */
void WelsLogDefault (void* pCtx, const int32_t kiLevel, const str_t* kpFmtStr, va_list argv) {
  sWelsEncCtx* pEncCtx	= (sWelsEncCtx*)pCtx;
  iWelsLogLevel		 iVal	= (kiLevel & g_iLevelLog);

  if (0 == iVal || NULL == pEncCtx) {	// such iLevel not enabled
    return;
  } else {
    str_t pBuf[WELS_LOG_BUF_SIZE + 1] = {0};
    const int32_t kiBufSize = sizeof (pBuf) / sizeof (pBuf[0]) - 1;
    int32_t iCurUsed = 0;
    int32_t iBufUsed = 0;
    int32_t iBufLeft = kiBufSize - iBufUsed;

    if (pEncCtx) {
      SWelsTime tTime;

      WelsGetTimeOfDay(&tTime);
      iCurUsed = WelsSnprintf (&pBuf[iBufUsed], iBufLeft, "[0x%p @ ", pEncCtx);	// confirmed_safe_unsafe_usage
      if (iCurUsed >= 0) {
        iBufUsed += iCurUsed;
        iBufLeft -= iCurUsed;
      }

      if (iBufLeft > 0) {
        iCurUsed = GetCodeName (&pBuf[iBufUsed], iBufLeft);
        if (iCurUsed > 0) {
          iBufUsed += iCurUsed;
          iBufLeft -= iCurUsed;
        }
        pBuf[iBufUsed] = ' ';
        ++ iBufUsed;
        -- iBufLeft;

        iCurUsed = GetLibName (&pBuf[iBufUsed], iBufLeft);
        if (iCurUsed > 0) {
          iBufUsed += iCurUsed;
          iBufLeft -= iCurUsed;
        }
        pBuf[iBufUsed] = ' ';
        ++ iBufUsed;
        -- iBufLeft;

        pBuf[iBufUsed] = 'v';
        ++ iBufUsed;
        -- iBufLeft;
        iCurUsed = GetVerNum (&pBuf[iBufUsed], iBufLeft);
        if (iCurUsed > 0) {
          iBufUsed += iCurUsed;
          iBufLeft -= iCurUsed;
        }
        pBuf[iBufUsed] = ' ';
        ++ iBufUsed;
        -- iBufLeft;
      }

      if (iBufLeft > 0) {
        iCurUsed = WelsStrftime (&pBuf[iBufUsed], iBufLeft, "%y-%m-%d %H:%M:%S", &tTime);
        if (iCurUsed > 0) {
          iBufUsed += iCurUsed;
          iBufLeft -= iCurUsed;
        }
      } else {
        return;
      }

      if (iBufLeft > 0) {
        iCurUsed = WelsSnprintf (&pBuf[iBufUsed], iBufLeft, ".%3.3u]: ", tTime.millitm);	// confirmed_safe_unsafe_usage
        if (iCurUsed >= 0) {
          iBufUsed += iCurUsed;
          iBufLeft -= iCurUsed;
        }
      } else {
        return;
      }
    }

    // fixed stack corruption issue on vs2008
    if (iBufLeft > 0) {
      int32_t i_shift = 0;
      str_t* pStr = NULL;
      pStr	= GetLogTag (kiLevel, &i_shift);
      if (NULL != pStr) {
        int32_t iLenTag = strlen (pStr);	// confirmed_safe_unsafe_usage
        STRCAT (&pBuf[iBufUsed], iBufLeft, pStr);	// confirmed_safe_unsafe_usage
        iBufUsed += iLenTag;
        pBuf[iBufUsed] = ' ';
        iBufUsed++;
        ++iLenTag;
        iBufLeft -= iLenTag;
      }
    }
    if (iBufLeft > 0) {
      iCurUsed = WelsVsnprintf (&pBuf[iBufUsed], iBufLeft, kpFmtStr, argv);	// confirmed_safe_unsafe_usage
      if (iCurUsed > 0) {
        iBufUsed += iCurUsed;
        iBufLeft -= iCurUsed;
      }
    }
#ifdef ENABLE_TRACE_FILE
    if (NULL != pEncCtx && NULL != pEncCtx->pFileLog) {
      if (pEncCtx->uiSizeLog > MAX_TRACE_LOG_SIZE) {
        if (0 == WelsFseek (pEncCtx->pFileLog, 0L, SEEK_SET))
          pEncCtx->uiSizeLog = 0;
      }
      if (iBufUsed > 0 && iBufUsed < WELS_LOG_BUF_SIZE) {
        iCurUsed = WelsFwrite (pBuf, 1, iBufUsed, pEncCtx->pFileLog);
        WelsFflush (pEncCtx->pFileLog);
        if (iCurUsed == iBufUsed)
          pEncCtx->uiSizeLog += iBufUsed;
      }
    } else {
#if defined(_WIN32) && defined(_DEBUG)
      OutputDebugStringA (pBuf);
#endif
    }
#endif//ENABLE_TRACE_FILE
  }
}
void WelsLogNil (void* pCtx, const int32_t kiLevel, const str_t* kpFmtStr, va_list argv) {
  // NULL implementation
}

/*!
*************************************************************************************
* \brief	reopen log file when finish setting current path
*
* \param	pCtx		context pCtx
* \param	pCurPath	current path string
*
* \return	NONE
*
* \note	N/A
*************************************************************************************
*/
void WelsReopenTraceFile (void* pCtx, str_t* pCurPath) {
#ifdef ENABLE_TRACE_FILE
  sWelsEncCtx* pEncCtx	= (sWelsEncCtx*)pCtx;
  if (wlog == WelsLogDefault) {
    if (pEncCtx->pFileLog != NULL) {
      WelsFclose (pEncCtx->pFileLog);
      pEncCtx->pFileLog = NULL;
    }
    pEncCtx->uiSizeLog	= 0;
    pEncCtx->pFileLog	= WelsFopen ("wels_encoder_trace.txt", "wt+");	// confirmed_safe_unsafe_usage
  }
#endif//ENABLE_TRACE_FILE
}

/*!
 *************************************************************************************
 * \brief	set log iLevel from external call
 *
 * \param	iLevel	iLevel of log
 *
 * \return	NONE
 *
 * \note	can be able to control log iLevel dynamically
 *************************************************************************************
 */
void WelsSetLogLevel (const int32_t kiLevel) {
  iWelsLogLevel iVal = 0;
  if (kiLevel & WELS_LOG_ERROR) {
    iVal |= WELS_LOG_ERROR;
  }
  if (kiLevel & WELS_LOG_WARNING) {
    iVal |= WELS_LOG_WARNING;
  }
  if (kiLevel & WELS_LOG_INFO) {
    iVal |= WELS_LOG_INFO;
  }
  if (kiLevel & WELS_LOG_DEBUG) {
    iVal |= WELS_LOG_DEBUG;
  }
  g_iLevelLog	= iVal;
}

/*!
 *************************************************************************************
 * \brief	get log iLevel from external call
 *
 * \param	N/A
 *
 * \return	current iLevel of log used in codec internal
 *
 * \note	can be able to get log iLevel of internal codec applicable
 *************************************************************************************
 */
int32_t WelsGetLogLevel (void) {
  return g_iLevelLog;
}

/*!
 *************************************************************************************
 * \brief	set log callback from external call
 *
 * \param	_log	log function routine
 *
 * \return	NONE
 *
 * \note	N/A
 *************************************************************************************
 */
void WelsSetLogCallback (PWelsLogCallbackFunc _log) {
  wlog	= _log;
}

void WelsLogCall (void* pCtx, int32_t iLevel, const str_t* kpFmt, va_list vl) {
  wlog (pCtx, iLevel, kpFmt, vl);
}

void WelsLog (void* pCtx, int32_t iLevel, const str_t* kpFmt, ...) {
  va_list vl;
  va_start (vl, kpFmt);
  WelsLogCall (pCtx, iLevel, kpFmt, vl);
  va_end (vl);
}

#ifndef CALC_PSNR
#define CONST_FACTOR_PSNR	(10.0 / log(10.0))	// for good computation
#define CALC_PSNR(w, h, s)	((real32_t)(CONST_FACTOR_PSNR * log( 65025.0 * w * h / iSqe )))
#endif//CALC_PSNR

/*
 *	PSNR calculation routines
 */
/*!
 *************************************************************************************
 * \brief	PSNR calculation utilization in Wels
 *
 * \param	pTarPic		target picture to be calculated in Picture pData format
 * \param	iTarStride	stride of target picture pData pBuffer
 * \param 	pRefPic		base referencing picture samples
 * \param	iRefStride	stride of reference picture pData pBuffer
 * \param	iWidth		picture iWidth in pixel
 * \param	iHeight		picture iHeight in pixel
 *
 * \return	actual PSNR result;
 *
 * \note	N/A
 *************************************************************************************
 */
real32_t WelsCalcPsnr (const void* kpTarPic,
                       const int32_t kiTarStride,
                       const void* kpRefPic,
                       const int32_t kiRefStride,
                       const int32_t kiWidth,
                       const int32_t kiHeight) {
  int64_t	iSqe = 0;
  int32_t x, y;
  uint8_t* pTar = (uint8_t*)kpTarPic;
  uint8_t* pRef = (uint8_t*)kpRefPic;

  if (NULL == pTar || NULL == pRef)
    return (-1.0f);

  for (y = 0; y < kiHeight; ++ y) {	// OPTable !!
    for (x = 0; x < kiWidth; ++ x) {
      const int32_t kiT = pTar[y * kiTarStride + x] - pRef[y * kiRefStride + x];
      iSqe	+= kiT * kiT;
    }
  }
  if (0 == iSqe) {
    return (99.99f);
  }
  return CALC_PSNR (kiWidth, kiHeight, iSqe);
}

}
<commit_msg>Use WelsSnprintf instead of a combination of strlen and STRNCAT<commit_after>/*!
 * \copy
 *     Copyright (c)  2009-2013, Cisco Systems
 *     All rights reserved.
 *
 *     Redistribution and use in source and binary forms, with or without
 *     modification, are permitted provided that the following conditions
 *     are met:
 *
 *        * Redistributions of source code must retain the above copyright
 *          notice, this list of conditions and the following disclaimer.
 *
 *        * Redistributions 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.
 *
 *     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
 *     COPYRIGHT HOLDER 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.
 *
 *
 * \file	utils.c
 *
 * \brief	common tool/function utilization
 *
 * \date	03/10/2009 Created
 *
 *************************************************************************************
 */
#if defined(_WIN32)
#include <windows.h>
#include <sys/types.h>
#include <sys/timeb.h>
#ifndef _MSC_VER
#include <sys/time.h>
#endif
#else
#include <sys/time.h>
#endif

#include "utils.h"
#include "property.h"
#include "encoder_context.h"
#include "property.h"
#include "crt_util_safe_x.h"	// Safe CRT routines like utils for cross platforms

namespace WelsSVCEnc {

void WelsLogDefault (void* pCtx, const int32_t kiLevel, const str_t* kpFmtStr, va_list argv);
void WelsLogNil (void* pCtx, const int32_t kiLevel, const str_t* kpFmtStr, va_list argv);

real32_t WelsCalcPsnr (const void* kpTarPic,
                       const int32_t kiTarStride,
                       const void* kpRefPic,
                       const int32_t kiRefStride,
                       const int32_t kiWidth,
                       const int32_t kiHeight);

// to fill default routines
#ifdef ENABLE_TRACE_FILE
PWelsLogCallbackFunc wlog	= WelsLogDefault;
#else
PWelsLogCallbackFunc wlog	= WelsLogNil;
#endif

iWelsLogLevel		g_iLevelLog	= WELS_LOG_DEFAULT;	// default log iLevel
int32_t			g_iSizeLogBuf	= 1024;			// pBuffer size for each log output

/*
 *	Log output routines
 */

/*!
 * \brief	get log tag
 * \param	kiLevel		log iLevel
 * \return  tag of log iLevel
 */
static inline str_t* GetLogTag (const int32_t kiLevel, int32_t* pBit) {
  int32_t iShift	= 0;
  int32_t iVal		= 0;
  bool_t	bFound	= false;

  if (kiLevel <= 0 || kiLevel > (1 << (WELS_LOG_LEVEL_COUNT - 1)) || NULL == pBit)
    return NULL;

  for (;;) {
    if (iShift >= WELS_LOG_LEVEL_COUNT)
      break;
    iVal	= (1 << iShift);
    if (iVal == kiLevel) {
      bFound	= true;
      break;
    }
    ++ iShift;
  }

  if (bFound) {
    *pBit	= iShift;
    return (str_t*)g_sWelsLogTags[iShift];
  }
  return NULL;
}

/*!
 *************************************************************************************
 * \brief	System trace log output in Wels
 *
 * \param	pCtx	instance pointer
 * \param	kiLevel	log iLevel ( WELS_LOG_QUIET, ERROR, WARNING, INFO, DEBUG )
 * \param	kpFmtStr	formated string to mount
 * \param 	argv	pData string argument
 *
 * \return	NONE
 *
 * \note	N/A
 *************************************************************************************
 */
void WelsLogDefault (void* pCtx, const int32_t kiLevel, const str_t* kpFmtStr, va_list argv) {
  sWelsEncCtx* pEncCtx	= (sWelsEncCtx*)pCtx;
  iWelsLogLevel		 iVal	= (kiLevel & g_iLevelLog);

  if (0 == iVal || NULL == pEncCtx) {	// such iLevel not enabled
    return;
  } else {
    str_t pBuf[WELS_LOG_BUF_SIZE + 1] = {0};
    const int32_t kiBufSize = sizeof (pBuf) / sizeof (pBuf[0]) - 1;
    int32_t iCurUsed = 0;
    int32_t iBufUsed = 0;
    int32_t iBufLeft = kiBufSize - iBufUsed;

    if (pEncCtx) {
      SWelsTime tTime;

      WelsGetTimeOfDay(&tTime);
      iCurUsed = WelsSnprintf (&pBuf[iBufUsed], iBufLeft, "[0x%p @ ", pEncCtx);	// confirmed_safe_unsafe_usage
      if (iCurUsed >= 0) {
        iBufUsed += iCurUsed;
        iBufLeft -= iCurUsed;
      }

      if (iBufLeft > 0) {
        iCurUsed = GetCodeName (&pBuf[iBufUsed], iBufLeft);
        if (iCurUsed > 0) {
          iBufUsed += iCurUsed;
          iBufLeft -= iCurUsed;
        }
        pBuf[iBufUsed] = ' ';
        ++ iBufUsed;
        -- iBufLeft;

        iCurUsed = GetLibName (&pBuf[iBufUsed], iBufLeft);
        if (iCurUsed > 0) {
          iBufUsed += iCurUsed;
          iBufLeft -= iCurUsed;
        }
        pBuf[iBufUsed] = ' ';
        ++ iBufUsed;
        -- iBufLeft;

        pBuf[iBufUsed] = 'v';
        ++ iBufUsed;
        -- iBufLeft;
        iCurUsed = GetVerNum (&pBuf[iBufUsed], iBufLeft);
        if (iCurUsed > 0) {
          iBufUsed += iCurUsed;
          iBufLeft -= iCurUsed;
        }
        pBuf[iBufUsed] = ' ';
        ++ iBufUsed;
        -- iBufLeft;
      }

      if (iBufLeft > 0) {
        iCurUsed = WelsStrftime (&pBuf[iBufUsed], iBufLeft, "%y-%m-%d %H:%M:%S", &tTime);
        if (iCurUsed > 0) {
          iBufUsed += iCurUsed;
          iBufLeft -= iCurUsed;
        }
      } else {
        return;
      }

      if (iBufLeft > 0) {
        iCurUsed = WelsSnprintf (&pBuf[iBufUsed], iBufLeft, ".%3.3u]: ", tTime.millitm);	// confirmed_safe_unsafe_usage
        if (iCurUsed >= 0) {
          iBufUsed += iCurUsed;
          iBufLeft -= iCurUsed;
        }
      } else {
        return;
      }
    }

    // fixed stack corruption issue on vs2008
    if (iBufLeft > 0) {
      int32_t i_shift = 0;
      str_t* pStr = NULL;
      pStr	= GetLogTag (kiLevel, &i_shift);
      if (NULL != pStr) {
        iCurUsed = WelsSnprintf (&pBuf[iBufUsed], iBufLeft, "%s ", pStr);
        if (iCurUsed >= 0) {
          iBufUsed += iCurUsed;
          iBufLeft -= iCurUsed;
        }
      }
    }
    if (iBufLeft > 0) {
      iCurUsed = WelsVsnprintf (&pBuf[iBufUsed], iBufLeft, kpFmtStr, argv);	// confirmed_safe_unsafe_usage
      if (iCurUsed > 0) {
        iBufUsed += iCurUsed;
        iBufLeft -= iCurUsed;
      }
    }
#ifdef ENABLE_TRACE_FILE
    if (NULL != pEncCtx && NULL != pEncCtx->pFileLog) {
      if (pEncCtx->uiSizeLog > MAX_TRACE_LOG_SIZE) {
        if (0 == WelsFseek (pEncCtx->pFileLog, 0L, SEEK_SET))
          pEncCtx->uiSizeLog = 0;
      }
      if (iBufUsed > 0 && iBufUsed < WELS_LOG_BUF_SIZE) {
        iCurUsed = WelsFwrite (pBuf, 1, iBufUsed, pEncCtx->pFileLog);
        WelsFflush (pEncCtx->pFileLog);
        if (iCurUsed == iBufUsed)
          pEncCtx->uiSizeLog += iBufUsed;
      }
    } else {
#if defined(_WIN32) && defined(_DEBUG)
      OutputDebugStringA (pBuf);
#endif
    }
#endif//ENABLE_TRACE_FILE
  }
}
void WelsLogNil (void* pCtx, const int32_t kiLevel, const str_t* kpFmtStr, va_list argv) {
  // NULL implementation
}

/*!
*************************************************************************************
* \brief	reopen log file when finish setting current path
*
* \param	pCtx		context pCtx
* \param	pCurPath	current path string
*
* \return	NONE
*
* \note	N/A
*************************************************************************************
*/
void WelsReopenTraceFile (void* pCtx, str_t* pCurPath) {
#ifdef ENABLE_TRACE_FILE
  sWelsEncCtx* pEncCtx	= (sWelsEncCtx*)pCtx;
  if (wlog == WelsLogDefault) {
    if (pEncCtx->pFileLog != NULL) {
      WelsFclose (pEncCtx->pFileLog);
      pEncCtx->pFileLog = NULL;
    }
    pEncCtx->uiSizeLog	= 0;
    pEncCtx->pFileLog	= WelsFopen ("wels_encoder_trace.txt", "wt+");	// confirmed_safe_unsafe_usage
  }
#endif//ENABLE_TRACE_FILE
}

/*!
 *************************************************************************************
 * \brief	set log iLevel from external call
 *
 * \param	iLevel	iLevel of log
 *
 * \return	NONE
 *
 * \note	can be able to control log iLevel dynamically
 *************************************************************************************
 */
void WelsSetLogLevel (const int32_t kiLevel) {
  iWelsLogLevel iVal = 0;
  if (kiLevel & WELS_LOG_ERROR) {
    iVal |= WELS_LOG_ERROR;
  }
  if (kiLevel & WELS_LOG_WARNING) {
    iVal |= WELS_LOG_WARNING;
  }
  if (kiLevel & WELS_LOG_INFO) {
    iVal |= WELS_LOG_INFO;
  }
  if (kiLevel & WELS_LOG_DEBUG) {
    iVal |= WELS_LOG_DEBUG;
  }
  g_iLevelLog	= iVal;
}

/*!
 *************************************************************************************
 * \brief	get log iLevel from external call
 *
 * \param	N/A
 *
 * \return	current iLevel of log used in codec internal
 *
 * \note	can be able to get log iLevel of internal codec applicable
 *************************************************************************************
 */
int32_t WelsGetLogLevel (void) {
  return g_iLevelLog;
}

/*!
 *************************************************************************************
 * \brief	set log callback from external call
 *
 * \param	_log	log function routine
 *
 * \return	NONE
 *
 * \note	N/A
 *************************************************************************************
 */
void WelsSetLogCallback (PWelsLogCallbackFunc _log) {
  wlog	= _log;
}

void WelsLogCall (void* pCtx, int32_t iLevel, const str_t* kpFmt, va_list vl) {
  wlog (pCtx, iLevel, kpFmt, vl);
}

void WelsLog (void* pCtx, int32_t iLevel, const str_t* kpFmt, ...) {
  va_list vl;
  va_start (vl, kpFmt);
  WelsLogCall (pCtx, iLevel, kpFmt, vl);
  va_end (vl);
}

#ifndef CALC_PSNR
#define CONST_FACTOR_PSNR	(10.0 / log(10.0))	// for good computation
#define CALC_PSNR(w, h, s)	((real32_t)(CONST_FACTOR_PSNR * log( 65025.0 * w * h / iSqe )))
#endif//CALC_PSNR

/*
 *	PSNR calculation routines
 */
/*!
 *************************************************************************************
 * \brief	PSNR calculation utilization in Wels
 *
 * \param	pTarPic		target picture to be calculated in Picture pData format
 * \param	iTarStride	stride of target picture pData pBuffer
 * \param 	pRefPic		base referencing picture samples
 * \param	iRefStride	stride of reference picture pData pBuffer
 * \param	iWidth		picture iWidth in pixel
 * \param	iHeight		picture iHeight in pixel
 *
 * \return	actual PSNR result;
 *
 * \note	N/A
 *************************************************************************************
 */
real32_t WelsCalcPsnr (const void* kpTarPic,
                       const int32_t kiTarStride,
                       const void* kpRefPic,
                       const int32_t kiRefStride,
                       const int32_t kiWidth,
                       const int32_t kiHeight) {
  int64_t	iSqe = 0;
  int32_t x, y;
  uint8_t* pTar = (uint8_t*)kpTarPic;
  uint8_t* pRef = (uint8_t*)kpRefPic;

  if (NULL == pTar || NULL == pRef)
    return (-1.0f);

  for (y = 0; y < kiHeight; ++ y) {	// OPTable !!
    for (x = 0; x < kiWidth; ++ x) {
      const int32_t kiT = pTar[y * kiTarStride + x] - pRef[y * kiRefStride + x];
      iSqe	+= kiT * kiT;
    }
  }
  if (0 == iSqe) {
    return (99.99f);
  }
  return CALC_PSNR (kiWidth, kiHeight, iSqe);
}

}
<|endoftext|>


<commit_before>/**
 * @file storageHelperCreator.cc
 * @author Rafal Slota
 * @copyright (C) 2013 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in
 * 'LICENSE.txt'
 */

#include "helpers/storageHelperCreator.h"

#include "buffering/bufferAgent.h"
#include "posixHelper.h"
#include "proxyHelper.h"
#include "scheduler.h"

#if WITH_CEPH
#include "cephHelper.h"
#endif

#if WITH_S3
#include "s3Helper.h"
#endif

#if WITH_SWIFT
#include "swiftHelper.h"
#endif

namespace one {
namespace helpers {

#ifdef BUILD_PROXY_IO

StorageHelperCreator::StorageHelperCreator(
#if WITH_CEPH
    asio::io_service &cephService,
#endif
    asio::io_service &dioService,
#if WITH_S3
    asio::io_service &s3Service,
#endif
#if WITH_SWIFT
    asio::io_service &swiftService,
#endif
    communication::Communicator &communicator,
    std::size_t bufferSchedulerWorkers, buffering::BufferLimits bufferLimits)
    :
#if WITH_CEPH
    m_cephService{cephService}
    ,
#endif
    m_dioService{dioService}
    ,
#if WITH_S3
    m_s3Service{s3Service}
    ,
#endif
#if WITH_SWIFT
    m_swiftService{swiftService}
    ,
#endif
    m_scheduler{std::make_unique<Scheduler>(bufferSchedulerWorkers)}
    , m_bufferLimits{std::move(bufferLimits)}
    , m_communicator{communicator}
{
}
#else

StorageHelperCreator::StorageHelperCreator(
#if WITH_CEPH
    asio::io_service &cephService,
#endif
    asio::io_service &dioService,
#if WITH_S3
    asio::io_service &s3Service,
#endif
#if WITH_SWIFT
    asio::io_service &swiftService,
#endif
    std::size_t bufferSchedulerWorkers, buffering::BufferLimits bufferLimits)
    :
#if WITH_CEPH
    m_cephService{cephService}
    ,
#endif
    m_dioService{dioService}
    ,
#if WITH_S3
    m_s3Service{s3Service}
    ,
#endif
#if WITH_SWIFT
    m_swiftService{swiftService}
    ,
#endif
    m_scheduler{std::make_unique<Scheduler>(bufferSchedulerWorkers)}
    , m_bufferLimits{std::move(bufferLimits)}
{
}
#endif

StorageHelperCreator::~StorageHelperCreator() = default;

std::shared_ptr<StorageHelper> StorageHelperCreator::getStorageHelper(
    const folly::fbstring &name,
    const std::unordered_map<folly::fbstring, folly::fbstring> &args,
    const bool buffered)
{
    StorageHelperPtr helper;

    if (name == POSIX_HELPER_NAME)
        helper = PosixHelperFactory{m_dioService}.createStorageHelper(args);

#if WITH_CEPH
    if (name == CEPH_HELPER_NAME)
        helper = CephHelperFactory{m_cephService}.createStorageHelper(args);
#endif

#ifdef BUILD_PROXY_IO
    if (name == PROXY_HELPER_NAME)
        helper = ProxyHelperFactory{m_communicator}.createStorageHelper(args);
#endif

#if WITH_S3
    if (name == S3_HELPER_NAME)
        helper = S3HelperFactory{m_s3Service}.createStorageHelper(args);
#endif

#if WITH_SWIFT
    if (name == SWIFT_HELPER_NAME)
        helper = SwiftHelperFactory{m_swiftService}.createStorageHelper(args);
#endif

    if (!helper)
        throw std::system_error{
            std::make_error_code(std::errc::invalid_argument),
            "Invalid storage helper name: '" + name.toStdString() + "'"};

    if (buffered)
        return std::make_shared<buffering::BufferAgent>(
            m_bufferLimits, helper, *m_scheduler);

    return helper;
}

} // namespace helpers
} // namespace one
<commit_msg>Disable storage helpers buffering<commit_after>/**
 * @file storageHelperCreator.cc
 * @author Rafal Slota
 * @copyright (C) 2013 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in
 * 'LICENSE.txt'
 */

#include "helpers/storageHelperCreator.h"

#include "buffering/bufferAgent.h"
#include "posixHelper.h"
#include "proxyHelper.h"
#include "scheduler.h"

#if WITH_CEPH
#include "cephHelper.h"
#endif

#if WITH_S3
#include "s3Helper.h"
#endif

#if WITH_SWIFT
#include "swiftHelper.h"
#endif

namespace one {
namespace helpers {

#ifdef BUILD_PROXY_IO

StorageHelperCreator::StorageHelperCreator(
#if WITH_CEPH
    asio::io_service &cephService,
#endif
    asio::io_service &dioService,
#if WITH_S3
    asio::io_service &s3Service,
#endif
#if WITH_SWIFT
    asio::io_service &swiftService,
#endif
    communication::Communicator &communicator,
    std::size_t bufferSchedulerWorkers, buffering::BufferLimits bufferLimits)
    :
#if WITH_CEPH
    m_cephService{cephService}
    ,
#endif
    m_dioService{dioService}
    ,
#if WITH_S3
    m_s3Service{s3Service}
    ,
#endif
#if WITH_SWIFT
    m_swiftService{swiftService}
    ,
#endif
    m_scheduler{std::make_unique<Scheduler>(bufferSchedulerWorkers)}
    , m_bufferLimits{std::move(bufferLimits)}
    , m_communicator{communicator}
{
}
#else

StorageHelperCreator::StorageHelperCreator(
#if WITH_CEPH
    asio::io_service &cephService,
#endif
    asio::io_service &dioService,
#if WITH_S3
    asio::io_service &s3Service,
#endif
#if WITH_SWIFT
    asio::io_service &swiftService,
#endif
    std::size_t bufferSchedulerWorkers, buffering::BufferLimits bufferLimits)
    :
#if WITH_CEPH
    m_cephService{cephService}
    ,
#endif
    m_dioService{dioService}
    ,
#if WITH_S3
    m_s3Service{s3Service}
    ,
#endif
#if WITH_SWIFT
    m_swiftService{swiftService}
    ,
#endif
    m_scheduler{std::make_unique<Scheduler>(bufferSchedulerWorkers)}
    , m_bufferLimits{std::move(bufferLimits)}
{
}
#endif

StorageHelperCreator::~StorageHelperCreator() = default;

std::shared_ptr<StorageHelper> StorageHelperCreator::getStorageHelper(
    const folly::fbstring &name,
    const std::unordered_map<folly::fbstring, folly::fbstring> &args,
    const bool buffered)
{
    StorageHelperPtr helper;

    if (name == POSIX_HELPER_NAME)
        helper = PosixHelperFactory{m_dioService}.createStorageHelper(args);

#if WITH_CEPH
    if (name == CEPH_HELPER_NAME)
        helper = CephHelperFactory{m_cephService}.createStorageHelper(args);
#endif

#ifdef BUILD_PROXY_IO
    if (name == PROXY_HELPER_NAME)
        helper = ProxyHelperFactory{m_communicator}.createStorageHelper(args);
#endif

#if WITH_S3
    if (name == S3_HELPER_NAME)
        helper = S3HelperFactory{m_s3Service}.createStorageHelper(args);
#endif

#if WITH_SWIFT
    if (name == SWIFT_HELPER_NAME)
        helper = SwiftHelperFactory{m_swiftService}.createStorageHelper(args);
#endif

    if (!helper)
        throw std::system_error{
            std::make_error_code(std::errc::invalid_argument),
            "Invalid storage helper name: '" + name.toStdString() + "'"};

    //if (buffered)
    //    return std::make_shared<buffering::BufferAgent>(
    //        m_bufferLimits, helper, *m_scheduler);

    return helper;
}

} // namespace helpers
} // namespace one
<|endoftext|>