<commit_before>//===--- BindingInferenceTests.cpp ----------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "SemaFixture.h"
#include "swift/AST/Expr.h"
#include "swift/Sema/ConstraintSystem.h"
#include "llvm/ADT/SmallPtrSet.h"

using namespace swift;
using namespace swift::unittest;
using namespace swift::constraints;

TEST_F(SemaTest, TestIntLiteralBindingInference) {
  ConstraintSystemOptions options;
  options |= ConstraintSystemFlags::AllowUnresolvedTypeVariables;

  ConstraintSystem cs(DC, options);

  auto *intLiteral = IntegerLiteralExpr::createFromUnsigned(Context, 42);

  auto *literalTy = cs.createTypeVariable(cs.getConstraintLocator(intLiteral),
                                          /*options=*/0);

  cs.addConstraint(
      ConstraintKind::LiteralConformsTo, literalTy,
      Context.getProtocol(KnownProtocolKind::ExpressibleByIntegerLiteral)
          ->getDeclaredInterfaceType(),
      cs.getConstraintLocator(intLiteral));

  auto bindings = cs.inferBindingsFor(literalTy);

  ASSERT_EQ(bindings.Bindings.size(), (unsigned)1);

  const auto &binding = bindings.Bindings.front();

  ASSERT_TRUE(binding.BindingType->isEqual(getStdlibType("Int")));
  ASSERT_TRUE(binding.hasDefaultedLiteralProtocol());
}

TEST_F(SemaTest, TestTransitiveProtocolInference) {
  ConstraintSystemOptions options;
  ConstraintSystem cs(DC, options);

  auto *PD1 =
      new (Context) ProtocolDecl(DC, SourceLoc(), SourceLoc(),
                                 Context.getIdentifier("P1"), /*Inherited=*/{},
                                 /*trailingWhere=*/nullptr);
  PD1->setImplicit();

  auto *protocolTy1 = ProtocolType::get(PD1, Type(), Context);

  auto *GPT = cs.createTypeVariable(cs.getConstraintLocator({}),
                                    /*options=*/TVO_CanBindToNoEscape);

  cs.addConstraint(
      ConstraintKind::ConformsTo, GPT, protocolTy1,
      cs.getConstraintLocator({}, LocatorPathElt::TypeParameterRequirement(
                                      0, RequirementKind::Conformance)));

  // First, let's try inferring through a single conversion
  // relationship.
  {
    auto *typeVar = cs.createTypeVariable(cs.getConstraintLocator({}),
                                          /*options=*/0);

    cs.addConstraint(
        ConstraintKind::Conversion, typeVar, GPT,
        cs.getConstraintLocator({}, LocatorPathElt::ContextualType()));

    auto bindings = inferBindings(cs, typeVar);
    ASSERT_TRUE(bindings.Protocols.empty());

    const auto &inferredProtocols = bindings.TransitiveProtocols;
    ASSERT_TRUE(bool(inferredProtocols));
    ASSERT_EQ(inferredProtocols->size(), (unsigned)1);
    ASSERT_TRUE(
        (*inferredProtocols->begin())->getSecondType()->isEqual(protocolTy1));
  }
}
<commit_msg>[unittest/Sema] Cover transitive protocol inference with unit tests<commit_after>//===--- BindingInferenceTests.cpp ----------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "SemaFixture.h"
#include "swift/AST/Expr.h"
#include "swift/Sema/ConstraintSystem.h"
#include "llvm/ADT/SmallPtrSet.h"

using namespace swift;
using namespace swift::unittest;
using namespace swift::constraints;

TEST_F(SemaTest, TestIntLiteralBindingInference) {
  ConstraintSystemOptions options;
  options |= ConstraintSystemFlags::AllowUnresolvedTypeVariables;

  ConstraintSystem cs(DC, options);

  auto *intLiteral = IntegerLiteralExpr::createFromUnsigned(Context, 42);

  auto *literalTy = cs.createTypeVariable(cs.getConstraintLocator(intLiteral),
                                          /*options=*/0);

  cs.addConstraint(
      ConstraintKind::LiteralConformsTo, literalTy,
      Context.getProtocol(KnownProtocolKind::ExpressibleByIntegerLiteral)
          ->getDeclaredInterfaceType(),
      cs.getConstraintLocator(intLiteral));

  auto bindings = cs.inferBindingsFor(literalTy);

  ASSERT_EQ(bindings.Bindings.size(), (unsigned)1);

  const auto &binding = bindings.Bindings.front();

  ASSERT_TRUE(binding.BindingType->isEqual(getStdlibType("Int")));
  ASSERT_TRUE(binding.hasDefaultedLiteralProtocol());
}

// Given a set of inferred protocol requirements, make sure that
// all of the expected types are present.
static void verifyProtocolInferenceResults(
    const llvm::SmallPtrSetImpl<Constraint *> &protocols,
    ArrayRef<Type> expectedTypes) {
  ASSERT_TRUE(protocols.size() >= expectedTypes.size());

  llvm::SmallPtrSet<Type, 2> inferredProtocolTypes;
  for (auto *protocol : protocols)
    inferredProtocolTypes.insert(protocol->getSecondType());

  for (auto expectedTy : expectedTypes) {
    ASSERT_TRUE(inferredProtocolTypes.count(expectedTy));
  }
}

TEST_F(SemaTest, TestTransitiveProtocolInference) {
  ConstraintSystemOptions options;
  ConstraintSystem cs(DC, options);

  auto *protocolTy1 = createProtocol("P1");
  auto *protocolTy2 = createProtocol("P2");

  auto *GPT1 = cs.createTypeVariable(cs.getConstraintLocator({}),
                                     /*options=*/TVO_CanBindToNoEscape);
  auto *GPT2 = cs.createTypeVariable(cs.getConstraintLocator({}),
                                     /*options=*/TVO_CanBindToNoEscape);

  cs.addConstraint(
      ConstraintKind::ConformsTo, GPT1, protocolTy1,
      cs.getConstraintLocator({}, LocatorPathElt::TypeParameterRequirement(
                                      0, RequirementKind::Conformance)));

  cs.addConstraint(
      ConstraintKind::ConformsTo, GPT2, protocolTy2,
      cs.getConstraintLocator({}, LocatorPathElt::TypeParameterRequirement(
                                      0, RequirementKind::Conformance)));

  // First, let's try inferring through a single conversion
  // relationship.
  {
    auto *typeVar = cs.createTypeVariable(cs.getConstraintLocator({}),
                                          /*options=*/0);

    cs.addConstraint(
        ConstraintKind::Conversion, typeVar, GPT1,
        cs.getConstraintLocator({}, LocatorPathElt::ContextualType()));

    auto bindings = inferBindings(cs, typeVar);
    ASSERT_TRUE(bindings.Protocols.empty());
    ASSERT_TRUE(bool(bindings.TransitiveProtocols));
    verifyProtocolInferenceResults(*bindings.TransitiveProtocols,
                                   {protocolTy1});
  }

  // Now, let's make sure that protocol requirements could be propagated
  // down conversion/equality chains through multiple hops.
  {
    // GPT1 is a subtype of GPT2 and GPT2 is convertible to a target type
    // variable, target should get both protocols inferred - P1 & P2.

    auto *typeVar = cs.createTypeVariable(cs.getConstraintLocator({}),
                                          /*options=*/0);

    cs.addConstraint(ConstraintKind::Subtype, GPT1, GPT2,
                     cs.getConstraintLocator({}));

    cs.addConstraint(ConstraintKind::Conversion, typeVar, GPT1,
                     cs.getConstraintLocator({}));

    auto bindings = inferBindings(cs, typeVar);
    ASSERT_TRUE(bindings.Protocols.empty());
    ASSERT_TRUE(bool(bindings.TransitiveProtocols));
    verifyProtocolInferenceResults(*bindings.TransitiveProtocols,
                                   {protocolTy1, protocolTy2});
  }
}

/// Let's try a more complicated situation where there protocols
/// are inferred from multiple sources on different levels of
/// convertion chain.
///
///  (P1) T0   T4 (T3)         T6 (P4)
///        \   /              /
///          T3 = T1 (P2) = T5
///           \   /
///             T2

TEST_F(SemaTest, TestComplexTransitiveProtocolInference) {
  ConstraintSystemOptions options;
  ConstraintSystem cs(DC, options);

  auto *protocolTy1 = createProtocol("P1");
  auto *protocolTy2 = createProtocol("P2");
  auto *protocolTy3 = createProtocol("P3");
  auto *protocolTy4 = createProtocol("P4");

  auto *nilLocator = cs.getConstraintLocator({});

  auto typeVar0 = cs.createTypeVariable(nilLocator, /*options=*/0);
  auto typeVar1 = cs.createTypeVariable(nilLocator, /*options=*/0);
  auto typeVar2 = cs.createTypeVariable(nilLocator, /*options=*/0);
  // Allow this type variable to be bound to l-value type to prevent
  // it from being merged with the rest of the type variables.
  auto typeVar3 =
      cs.createTypeVariable(nilLocator, /*options=*/TVO_CanBindToLValue);
  auto typeVar4 = cs.createTypeVariable(nilLocator, /*options=*/0);
  auto typeVar5 =
      cs.createTypeVariable(nilLocator, /*options=*/TVO_CanBindToLValue);
  auto typeVar6 = cs.createTypeVariable(nilLocator, /*options=*/0);

  cs.addConstraint(ConstraintKind::ConformsTo, typeVar0, protocolTy1,
                   nilLocator);
  cs.addConstraint(ConstraintKind::ConformsTo, typeVar1, protocolTy2,
                   nilLocator);
  cs.addConstraint(ConstraintKind::ConformsTo, typeVar4, protocolTy3,
                   nilLocator);
  cs.addConstraint(ConstraintKind::ConformsTo, typeVar6, protocolTy4,
                   nilLocator);

  // T3 <: T0, T3 <: T4
  cs.addConstraint(ConstraintKind::Conversion, typeVar3, typeVar0, nilLocator);
  cs.addConstraint(ConstraintKind::Conversion, typeVar3, typeVar4, nilLocator);

  // T2 <: T3, T2 <: T1, T3 == T1
  cs.addConstraint(ConstraintKind::Subtype, typeVar2, typeVar3, nilLocator);
  cs.addConstraint(ConstraintKind::Conversion, typeVar2, typeVar1, nilLocator);
  cs.addConstraint(ConstraintKind::Equal, typeVar3, typeVar1, nilLocator);
  // T1 == T5, T <: T6
  cs.addConstraint(ConstraintKind::Equal, typeVar1, typeVar5, nilLocator);
  cs.addConstraint(ConstraintKind::Conversion, typeVar5, typeVar6, nilLocator);

  auto bindingsForT1 = inferBindings(cs, typeVar1);
  auto bindingsForT2 = inferBindings(cs, typeVar2);
  auto bindingsForT3 = inferBindings(cs, typeVar3);
  auto bindingsForT5 = inferBindings(cs, typeVar5);

  ASSERT_TRUE(bool(bindingsForT1.TransitiveProtocols));
  verifyProtocolInferenceResults(*bindingsForT1.TransitiveProtocols,
                                 {protocolTy1, protocolTy3, protocolTy4});

  ASSERT_TRUE(bool(bindingsForT2.TransitiveProtocols));
  verifyProtocolInferenceResults(
      *bindingsForT2.TransitiveProtocols,
      {protocolTy1, protocolTy2, protocolTy3, protocolTy4});

  ASSERT_TRUE(bool(bindingsForT3.TransitiveProtocols));
  verifyProtocolInferenceResults(
      *bindingsForT3.TransitiveProtocols,
      {protocolTy1, protocolTy2, protocolTy3, protocolTy4});

  ASSERT_TRUE(bool(bindingsForT5.TransitiveProtocols));
  verifyProtocolInferenceResults(
      *bindingsForT5.TransitiveProtocols,
      {protocolTy1, protocolTy2, protocolTy3, protocolTy4});
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2014 Toshiaki Takada
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include <iostream>
#include <iomanip>
#include <algorithm>

#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <curlpp/Infos.hpp>
#include <curlpp/Exception.hpp>
#include "json/json.h"

#include "cli.hpp"
#include "cli_action.hpp"

using namespace curlpp;

CliActionHttp::CliActionHttp(Json::Value& http)
  : CliAction()
{
  method_ = http["method"].asString();
  path_ = http["path"].asString();
  format_ = http["format"].asString();

  Json::Value params = http["params"];

  if (!params.isNull())
    for (Json::Value::iterator it = params.begin();
         it != params.end(); ++it)
      param_token_[it.key().asString()] = *it;
}

bool
CliActionHttp::get_token(string& str, string& token)
{
  const char *p = str.c_str();
  size_t pos;

  // skip "/".
  pos = strspn(p, "/");
  if (pos > 0)
    str = str.substr(pos, string::npos);

  // stirng is empty.
  if (str.empty())
    return false;

  p = str.c_str();
  pos = strcspn(p, "/");
  token = str.substr(0, pos);

  str = str.substr(pos, string::npos);

  return true;
}

bool
CliActionHttp::handle(Cli *cli, ParamsMap& input)
{
  Json::Value json_params;
  Json::FastWriter writer;
  Json::Value null_value;
  string str(path_);
  string path;
  string token;
  const char *delim = "";

  if (cli->is_debug())
    {
      cout << "method: " << method_ << endl;
      cout << "path: " << path_ << endl;
    }

  for (ParamTokenMap::iterator it = param_token_.begin();
       it != param_token_.end(); ++it)
    {
      string key = it->first;
      replace(key.begin(), key.end(), '-', '_');

      if (cli->is_debug())
        cout << "param_token_[" << key << "] = " << it->second << endl;

      if (it->second.isNull())
        json_params[key] = null_value;
      else if (it->second.isBool())
        json_params[key] = it->second.asBool();
      else if (it->second.isUInt64())
        json_params[key] = it->second.asUInt64();
      else if (it->second.isInt64())
        json_params[key] = it->second.asInt64();
      else if (it->second.isString())
        {
          if (!input[it->second.asString()].empty())
            json_params[key] = input[it->second.asString()];
          else
            json_params[key] = it->second;
        }
    }

  // Generate path with parameter.
  while (get_token(str, token))
    {
      path += delim;

      if (token.c_str()[0] == ':')
        path += input[&token.c_str()[1]];
      else
        path += token;

      delim = "/";
    }

  string json_str = writer.write(json_params);

  if (cli->is_debug())
    cout << "json: " << json_str << endl;

  request(cli, method_, path, json_str);

  return true;
}

void
CliActionHttp::request(Cli *cli, string& method, string& path, string& json)
{
  if (method != "GET"
      && method != "POST"
      && method != "PUT"
      && method != "DELETE")
    return;

  string url("http://localhost");
  string api_prefix("/zebra/api");

  url += api_prefix;
  if (!path.empty())
    url += "/" + path;

  if (format_.empty())
    url += ".json";
  else
    url += "." + format_;

  try
    {
      Cleanup myCleanup;
      Easy req;
      stringstream result;

      req.setOpt(new options::Url(url));
      if (cli->is_debug())
        req.setOpt(new options::Verbose(true));

      list<string> header;
      header.push_back("Content-type: application/json");

      req.setOpt(new options::HttpHeader(header));
      req.setOpt(new options::CustomRequest(method));
      req.setOpt(new options::WriteStream(&result));

      if (method != "GET")
        {
          req.setOpt(new options::PostFields(json));
          req.setOpt(new options::PostFieldSize(json.size()));
        }

      req.perform();

      int status = infos::ResponseCode::get(req);
      switch (status / 100)
        {
        case 1:
        case 2:
          if (format_ == "cli")
            cout << result.str() << endl;
          break;
        case 3:
        case 4:
        case 5:
          cout << "HTTP Error: " << status << endl;
          break;
        }

      cli->set_result(result);
    }
  catch (curlpp::RuntimeError& e)
    {
      if (cli->is_debug())
        cout << e.what() << std::endl;
    }
  catch (curlpp::LogicError& e)
    {
      if (cli->is_debug())
        cout << e.what() << std::endl;
    }

  //  cout << endl;
}

CliActionMode::CliActionMode(Json::Value& mode)
  : CliAction()
{
  Json::Value name = mode["name"];
  Json::Value up = mode["up"];
  Json::Value params = mode["params"];

  if (!name.isNull())
    name_ = name.asString();
  if (!up.isNull())
    up_ = up.asUInt();

  if (!params.isNull())
    for (Json::Value::iterator it = params.begin();
         it != params.end(); ++it)
      params_.push_back((*it).asString());
}

bool
CliActionMode::handle(Cli *cli, ParamsMap& input)
{
  if (!name_.empty())
    {
      cli->mode_set(name_);

      // Derive parameters.
      cli->params_.clear();

      for (StringVector::iterator it = params_.begin();
           it != params_.end(); ++it)
        {
          ParamsMap::iterator is = input.find(*it);

          if (is != input.end())
            cli->params_[*it] = is->second;
        }
    }
  else if (up_)
    cli->mode_up(up_);

  return true;
}

bool
CliActionBuiltIn::handle(Cli *cli, ParamsMap& input)
{
  (void)input;

  //TODO
  StringVector vec;

  if (cli->built_in_[func_])
    cli->built_in_[func_](cli, vec);

  return true;
}
<commit_msg>Add dynamic key from input.  This is a little bit tricky.<commit_after>//
// Copyright (c) 2014 Toshiaki Takada
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include <iostream>
#include <iomanip>
#include <algorithm>

#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <curlpp/Infos.hpp>
#include <curlpp/Exception.hpp>
#include "json/json.h"

#include "cli.hpp"
#include "cli_action.hpp"

using namespace curlpp;

CliActionHttp::CliActionHttp(Json::Value& http)
  : CliAction()
{
  method_ = http["method"].asString();
  path_ = http["path"].asString();
  format_ = http["format"].asString();

  Json::Value params = http["params"];

  if (!params.isNull())
    for (Json::Value::iterator it = params.begin();
         it != params.end(); ++it)
      param_token_[it.key().asString()] = *it;
}

bool
CliActionHttp::get_token(string& str, string& token)
{
  const char *p = str.c_str();
  size_t pos;

  // skip "/".
  pos = strspn(p, "/");
  if (pos > 0)
    str = str.substr(pos, string::npos);

  // stirng is empty.
  if (str.empty())
    return false;

  p = str.c_str();
  pos = strcspn(p, "/");
  token = str.substr(0, pos);

  str = str.substr(pos, string::npos);

  return true;
}

bool
CliActionHttp::handle(Cli *cli, ParamsMap& input)
{
  Json::Value json_params;
  Json::FastWriter writer;
  Json::Value null_value;
  string str(path_);
  string path;
  string token;
  const char *delim = "";

  if (cli->is_debug())
    {
      cout << "method: " << method_ << endl;
      cout << "path: " << path_ << endl;
    }

  for (ParamTokenMap::iterator it = param_token_.begin();
       it != param_token_.end(); ++it)
    {
      string key = it->first;
      ParamsMap::iterator is;

      is = input.find(key);
      if (is != input.end())
        key = is->second;

      replace(key.begin(), key.end(), '-', '_');

      if (cli->is_debug())
        cout << "param_token_[" << key << "] = " << it->second << endl;

      if (it->second.isNull())
        json_params[key] = null_value;
      else if (it->second.isBool())
        json_params[key] = it->second.asBool();
      else if (it->second.isUInt64())
        json_params[key] = it->second.asUInt64();
      else if (it->second.isInt64())
        json_params[key] = it->second.asInt64();
      else if (it->second.isString())
        {
          if (!input[it->second.asString()].empty())
            json_params[key] = input[it->second.asString()];
          else
            json_params[key] = it->second;
        }
    }

  // Generate path with parameter.
  while (get_token(str, token))
    {
      path += delim;

      if (token.c_str()[0] == ':')
        path += input[&token.c_str()[1]];
      else
        path += token;

      delim = "/";
    }

  string json_str = writer.write(json_params);

  if (cli->is_debug())
    cout << "json: " << json_str << endl;

  request(cli, method_, path, json_str);

  return true;
}

void
CliActionHttp::request(Cli *cli, string& method, string& path, string& json)
{
  if (method != "GET"
      && method != "POST"
      && method != "PUT"
      && method != "DELETE")
    return;

  string url("http://localhost");
  string api_prefix("/zebra/api");

  url += api_prefix;
  if (!path.empty())
    url += "/" + path;

  if (format_.empty())
    url += ".json";
  else
    url += "." + format_;

  try
    {
      Cleanup myCleanup;
      Easy req;
      stringstream result;

      req.setOpt(new options::Url(url));
      if (cli->is_debug())
        req.setOpt(new options::Verbose(true));

      list<string> header;
      header.push_back("Content-type: application/json");

      req.setOpt(new options::HttpHeader(header));
      req.setOpt(new options::CustomRequest(method));
      req.setOpt(new options::WriteStream(&result));

      if (method != "GET")
        {
          req.setOpt(new options::PostFields(json));
          req.setOpt(new options::PostFieldSize(json.size()));
        }

      req.perform();

      int status = infos::ResponseCode::get(req);
      switch (status / 100)
        {
        case 1:
        case 2:
          if (format_ == "cli")
            cout << result.str() << endl;
          break;
        case 3:
        case 4:
        case 5:
          cout << "HTTP Error: " << status << endl;
          break;
        }

      cli->set_result(result);
    }
  catch (curlpp::RuntimeError& e)
    {
      if (cli->is_debug())
        cout << e.what() << std::endl;
    }
  catch (curlpp::LogicError& e)
    {
      if (cli->is_debug())
        cout << e.what() << std::endl;
    }

  //  cout << endl;
}

CliActionMode::CliActionMode(Json::Value& mode)
  : CliAction()
{
  Json::Value name = mode["name"];
  Json::Value up = mode["up"];
  Json::Value params = mode["params"];

  if (!name.isNull())
    name_ = name.asString();
  if (!up.isNull())
    up_ = up.asUInt();

  if (!params.isNull())
    for (Json::Value::iterator it = params.begin();
         it != params.end(); ++it)
      params_.push_back((*it).asString());
}

bool
CliActionMode::handle(Cli *cli, ParamsMap& input)
{
  if (!name_.empty())
    {
      cli->mode_set(name_);

      // Derive parameters.
      cli->params_.clear();

      for (StringVector::iterator it = params_.begin();
           it != params_.end(); ++it)
        {
          ParamsMap::iterator is = input.find(*it);

          if (is != input.end())
            cli->params_[*it] = is->second;
        }
    }
  else if (up_)
    cli->mode_up(up_);

  return true;
}

bool
CliActionBuiltIn::handle(Cli *cli, ParamsMap& input)
{
  (void)input;

  //TODO
  StringVector vec;

  if (cli->built_in_[func_])
    cli->built_in_[func_](cli, vec);

  return true;
}
<|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

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

=========================================================================*/
#include "otbWrapperOutputImageParameter.h"
#include "itkCastImageFilter.h"
#include "itkVectorCastImageFilter.h"

namespace otb
{
namespace Wrapper
{

OutputImageParameter::OutputImageParameter()
: m_PixelType(ImagePixelType_float)
{
  this->SetName("Output Image");
  this->SetKey("out");

  this->InitializeWriters();
}

OutputImageParameter::~OutputImageParameter()
{
}

void OutputImageParameter::InitializeWriters()
{
  m_Int8Writer = Int8WriterType::New();
  m_UInt8Writer = UInt8WriterType::New();
  m_Int16Writer = Int16WriterType::New();
  m_UInt16Writer = UInt16WriterType::New();
  m_Int32Writer = Int32WriterType::New();
  m_UInt32Writer = UInt32WriterType::New();
  m_FloatWriter = FloatWriterType::New();
  m_DoubleWriter = DoubleWriterType::New();

  m_RGBAUInt8Writer = RGBAUInt8WriterType::New();

  m_VectorInt8Writer = VectorInt8WriterType::New();
  m_VectorUInt8Writer = VectorUInt8WriterType::New();
  m_VectorInt16Writer = VectorInt16WriterType::New();
  m_VectorUInt16Writer = VectorUInt16WriterType::New();
  m_VectorInt32Writer = VectorInt32WriterType::New();
  m_VectorUInt32Writer = VectorUInt32WriterType::New();
  m_VectorFloatWriter = VectorFloatWriterType::New();
  m_VectorDoubleWriter = VectorDoubleWriterType::New();
}

#define otbCastAndWriteImageMacro(InputImageType, OutputImageType, writer) \
  {                                                                     \
    typedef itk::CastImageFilter<InputImageType, OutputImageType> CastFilterType; \
    typename CastFilterType::Pointer caster = CastFilterType::New();    \
    caster->SetInput( dynamic_cast<InputImageType*>(m_Image.GetPointer()) ); \
    writer->SetFileName( this->GetFileName() );                         \
    writer->SetInput(caster->GetOutput());                              \
    writer->Update();                                                   \
  }

template <class TInputImageType>
void
OutputImageParameter::SwitchImageWrite()
{
  switch(m_PixelType )
    {
    case ImagePixelType_int8:
    {
    otbCastAndWriteImageMacro(TInputImageType, Int8ImageType, m_Int8Writer);
    break;
    }
    case ImagePixelType_uint8:
    {
   std::cout<<"Write, output is image uint8"<<std::endl;
    otbCastAndWriteImageMacro(TInputImageType, UInt8ImageType, m_UInt8Writer);
    break;
    }
    case ImagePixelType_int16:
    {
    otbCastAndWriteImageMacro(TInputImageType, Int16ImageType, m_Int16Writer);
    break;
    }
    case ImagePixelType_uint16:
    {
    otbCastAndWriteImageMacro(TInputImageType, UInt16ImageType, m_UInt16Writer);
    break;
    }
    case ImagePixelType_int32:
    {
    otbCastAndWriteImageMacro(TInputImageType, Int32ImageType, m_Int32Writer);
    break;
    }
    case ImagePixelType_uint32:
    {
    otbCastAndWriteImageMacro(TInputImageType, UInt32ImageType, m_UInt32Writer);
    break;
    }
    case ImagePixelType_float:
    {
   std::cout<<"Write, output is image float"<<std::endl;
    otbCastAndWriteImageMacro(TInputImageType, FloatImageType, m_FloatWriter);
    break;
    }
    case ImagePixelType_double:
    {
 std::cout<<"Write, output is image double"<<std::endl;
    otbCastAndWriteImageMacro(TInputImageType, DoubleImageType, m_DoubleWriter);
    break;
    }
    }
}

template <class TInputVectorImageType>
void
OutputImageParameter::SwitchVectorImageWrite()
  {
  switch(m_PixelType )
    {
    case ImagePixelType_int8:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, Int8VectorImageType, m_VectorInt8Writer);
    break;
    }
    case ImagePixelType_uint8:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, UInt8VectorImageType, m_VectorUInt8Writer);
    break;
    }
    case ImagePixelType_int16:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, Int16VectorImageType, m_VectorInt16Writer);
    break;
    }
    case ImagePixelType_uint16:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, UInt16VectorImageType, m_VectorUInt16Writer);
    break;
    }
    case ImagePixelType_int32:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, Int32VectorImageType, m_VectorInt32Writer);
    break;
    }
    case ImagePixelType_uint32:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, UInt32VectorImageType, m_VectorUInt32Writer);
    break;
    }
    case ImagePixelType_float:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, FloatVectorImageType, m_VectorFloatWriter);
    break;
    }
    case ImagePixelType_double:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, DoubleVectorImageType, m_VectorDoubleWriter);
    break;
    }
    }
  }

template <class TInputRGBAImageType>
void
OutputImageParameter::SwitchRGBAImageWrite()
  {
  switch(m_PixelType )
    {
    case ImagePixelType_int8:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, Int8RGBAImageType, m_RGBAInt8Writer);
    break;
    }
    case ImagePixelType_uint8:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, UInt8RGBAImageType, m_RGBAUInt8Writer);
    break;
    }
    case ImagePixelType_int16:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, Int16RGBAImageType, m_RGBAInt16Writer);
    break;
    }
    case ImagePixelType_uint16:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, UInt16RGBAImageType, m_RGBAUInt16Writer);
    break;
    }
    case ImagePixelType_int32:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, Int32RGBAImageType, m_RGBAInt32Writer);
    break;
    }
    case ImagePixelType_uint32:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, UInt32RGBAImageType, m_RGBAUInt32Writer);
    break;
    }
    case ImagePixelType_float:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, FloatRGBAImageType, m_RGBAFloatWriter);
    break;
    }
    case ImagePixelType_double:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, DoubleRGBAImageType, m_RGBADoubleWriter);
    break;
    }
    }
  }

void
OutputImageParameter::Write()
{
  m_Image->UpdateOutputInformation();

  if (dynamic_cast<Int8ImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<Int8ImageType>();
    }
  else if (dynamic_cast<UInt8ImageType*>(m_Image.GetPointer()))
    {
    std::cout<<"Write, input is image uint8"<<std::endl;
    SwitchImageWrite<UInt8ImageType>();
    }
  else if (dynamic_cast<Int16ImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<Int16ImageType>();
    }
  else if (dynamic_cast<UInt16ImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<UInt16ImageType>();
    }
  else if (dynamic_cast<Int32ImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<Int32ImageType>();
    }
  else if (dynamic_cast<UInt32ImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<UInt32ImageType>();
    }
  else if (dynamic_cast<FloatImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<FloatImageType>();
    }
  else if (dynamic_cast<DoubleImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<DoubleImageType>();
    }
  else if (dynamic_cast<Int8VectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<Int8VectorImageType>();
    }
  else if (dynamic_cast<UInt8VectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<UInt8VectorImageType>();
    }
  else if (dynamic_cast<Int16VectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<Int16VectorImageType>();
    }
  else if (dynamic_cast<UInt16VectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<UInt16VectorImageType>();
    }
  else if (dynamic_cast<Int32VectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<Int32VectorImageType>();
    }
  else if (dynamic_cast<UInt32VectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<UInt32VectorImageType>();
    }
  else if (dynamic_cast<FloatVectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<FloatVectorImageType>();
    }
  else if (dynamic_cast<DoubleVectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<DoubleVectorImageType>();
    }
  else if (dynamic_cast<Int8ImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<Int8RGBAImageType>();
    }
  else if (dynamic_cast<UInt8RGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<UInt8RGBAImageType>();
    }
  else if (dynamic_cast<Int16RGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<Int16RGBAImageType>();
    }
  else if (dynamic_cast<UInt16RGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<UInt16RGBAImageType>();
    }
  else if (dynamic_cast<Int32RGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<Int32RGBAImageType>();
    }
  else if (dynamic_cast<UInt32RGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<UInt32RGBAImageType>();
    }
  else if (dynamic_cast<FloatRGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<FloatRGBAImageType>();
    }
  else if (dynamic_cast<DoubleRGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<DoubleRGBAImageType>();
    }
  else
    {
    itkExceptionMacro("Unknown image type");
    }
  }

itk::ProcessObject*
OutputImageParameter::GetWriter()
{
  int type = 0;
  // 0 : image
  // 1 : VectorImage
  // 2 : RGBAImage

  if ( dynamic_cast<Int8VectorImageType*>(  m_Image.GetPointer()) ||
       dynamic_cast<UInt8VectorImageType*>( m_Image.GetPointer()) ||
       dynamic_cast<Int16VectorImageType*>( m_Image.GetPointer()) ||
       dynamic_cast<UInt16VectorImageType*>(m_Image.GetPointer()) ||
       dynamic_cast<Int32VectorImageType*>( m_Image.GetPointer()) ||
       dynamic_cast<UInt32VectorImageType*>(m_Image.GetPointer()) ||
       dynamic_cast<FloatVectorImageType*>( m_Image.GetPointer()) ||
       dynamic_cast<DoubleVectorImageType*>(m_Image.GetPointer())   )
    {
    type = 1;
    }
  else if( dynamic_cast<Int8RGBAImageType*>(  m_Image.GetPointer()) ||
           dynamic_cast<UInt8RGBAImageType*>( m_Image.GetPointer()) ||
           dynamic_cast<Int16RGBAImageType*>( m_Image.GetPointer()) ||
           dynamic_cast<UInt16RGBAImageType*>(m_Image.GetPointer()) ||
           dynamic_cast<Int32RGBAImageType*>( m_Image.GetPointer()) ||
           dynamic_cast<UInt32RGBAImageType*>(m_Image.GetPointer()) ||
           dynamic_cast<FloatRGBAImageType*>( m_Image.GetPointer()) ||
           dynamic_cast<DoubleRGBAImageType*>(m_Image.GetPointer())   )
    {
    type = 2;
    }

  itk::ProcessObject* writer = 0;
  switch ( GetPixelType() )
    {
    case ImagePixelType_int8:
    {
    if( type == 1 )
      writer = m_VectorInt8Writer;
    else if(type == 0)
      writer = m_Int8Writer;
    else
      writer = m_RGBAInt8Writer;
    break;
    }
    case ImagePixelType_uint8:
    {
    if( type == 1 )
      writer = m_VectorUInt8Writer;
    else if(type == 0)
      writer = m_UInt8Writer;
    else
      writer = m_RGBAUInt8Writer;
    break;
    }
    case ImagePixelType_int16:
    {
    if( type == 1 )
      writer = m_VectorInt16Writer;
    else if(type == 0)
      writer = m_Int16Writer;
    else
      writer = m_RGBAInt16Writer;
    break;
    }
    case ImagePixelType_uint16:
    {
    if( type == 1 )
      writer = m_VectorUInt16Writer;
    else if(type == 0)
      writer = m_UInt16Writer;
    else
      writer = m_RGBAUInt16Writer;
    break;
    }
    case ImagePixelType_int32:
    {
    if( type == 1 )
      writer = m_VectorInt32Writer;
    else if(type == 0)
      writer = m_Int32Writer;
    else
      writer = m_RGBAInt32Writer;
    break;
    }
    case ImagePixelType_uint32:
    {
    if( type == 1 )
      writer = m_VectorUInt32Writer;
    else if(type == 0)
      writer = m_UInt32Writer;
    else
      writer = m_RGBAUInt32Writer;
    break;
    }
    case ImagePixelType_float:
    {
    if( type == 1 )
      writer = m_VectorFloatWriter;
    else if(type == 0)
      writer = m_FloatWriter;
    else
      writer = m_RGBAFloatWriter;
    break;
    }
    case ImagePixelType_double:
    {
    if( type == 1 )
      writer = m_VectorDoubleWriter;
    else if(type == 0)
      writer = m_DoubleWriter;
    else
      writer = m_RGBADoubleWriter;
    break;
    }
    }
  return writer;
}

OutputImageParameter::ImageBaseType*
OutputImageParameter::GetValue( )
{
  return m_Image;
}

void
OutputImageParameter::SetValue(ImageBaseType* image)
{
  m_Image = image;
  SetActive(true);
}

bool
OutputImageParameter::HasValue() const
{
  std::string filename(this->GetFileName());
  return !filename.empty();
}

}
}
<commit_msg>ENH: add missing init<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

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

=========================================================================*/
#include "otbWrapperOutputImageParameter.h"
#include "itkCastImageFilter.h"
#include "itkVectorCastImageFilter.h"

namespace otb
{
namespace Wrapper
{

OutputImageParameter::OutputImageParameter()
: m_PixelType(ImagePixelType_float)
{
  this->SetName("Output Image");
  this->SetKey("out");

  this->InitializeWriters();
}

OutputImageParameter::~OutputImageParameter()
{
}

void OutputImageParameter::InitializeWriters()
{
  m_Int8Writer = Int8WriterType::New();
  m_UInt8Writer = UInt8WriterType::New();
  m_Int16Writer = Int16WriterType::New();
  m_UInt16Writer = UInt16WriterType::New();
  m_Int32Writer = Int32WriterType::New();
  m_UInt32Writer = UInt32WriterType::New();
  m_FloatWriter = FloatWriterType::New();
  m_DoubleWriter = DoubleWriterType::New();

  m_VectorInt8Writer = VectorInt8WriterType::New();
  m_VectorUInt8Writer = VectorUInt8WriterType::New();
  m_VectorInt16Writer = VectorInt16WriterType::New();
  m_VectorUInt16Writer = VectorUInt16WriterType::New();
  m_VectorInt32Writer = VectorInt32WriterType::New();
  m_VectorUInt32Writer = VectorUInt32WriterType::New();
  m_VectorFloatWriter = VectorFloatWriterType::New();
  m_VectorDoubleWriter = VectorDoubleWriterType::New();

  m_RGBAInt8Writer = RGBAInt8WriterType::New();
  m_RGBAUInt8Writer = RGBAUInt8WriterType::New();
  m_RGBAInt16Writer = RGBAInt16WriterType::New();
  m_RGBAUInt16Writer = RGBAUInt16WriterType::New();
  m_RGBAInt32Writer = RGBAInt32WriterType::New();
  m_RGBAUInt32Writer = RGBAUInt32WriterType::New();
  m_RGBAFloatWriter = RGBAFloatWriterType::New();
  m_RGBADoubleWriter = RGBADoubleWriterType::New();
}

#define otbCastAndWriteImageMacro(InputImageType, OutputImageType, writer) \
  {                                                                     \
    typedef itk::CastImageFilter<InputImageType, OutputImageType> CastFilterType; \
    typename CastFilterType::Pointer caster = CastFilterType::New();    \
    caster->SetInput( dynamic_cast<InputImageType*>(m_Image.GetPointer()) ); \
    writer->SetFileName( this->GetFileName() );                         \
    writer->SetInput(caster->GetOutput());                              \
    writer->Update();                                                   \
  }

template <class TInputImageType>
void
OutputImageParameter::SwitchImageWrite()
{
  switch(m_PixelType )
    {
    case ImagePixelType_int8:
    {
    otbCastAndWriteImageMacro(TInputImageType, Int8ImageType, m_Int8Writer);
    break;
    }
    case ImagePixelType_uint8:
    {
   std::cout<<"Write, output is image uint8"<<std::endl;
    otbCastAndWriteImageMacro(TInputImageType, UInt8ImageType, m_UInt8Writer);
    break;
    }
    case ImagePixelType_int16:
    {
    otbCastAndWriteImageMacro(TInputImageType, Int16ImageType, m_Int16Writer);
    break;
    }
    case ImagePixelType_uint16:
    {
    otbCastAndWriteImageMacro(TInputImageType, UInt16ImageType, m_UInt16Writer);
    break;
    }
    case ImagePixelType_int32:
    {
    otbCastAndWriteImageMacro(TInputImageType, Int32ImageType, m_Int32Writer);
    break;
    }
    case ImagePixelType_uint32:
    {
    otbCastAndWriteImageMacro(TInputImageType, UInt32ImageType, m_UInt32Writer);
    break;
    }
    case ImagePixelType_float:
    {
   std::cout<<"Write, output is image float"<<std::endl;
    otbCastAndWriteImageMacro(TInputImageType, FloatImageType, m_FloatWriter);
    break;
    }
    case ImagePixelType_double:
    {
 std::cout<<"Write, output is image double"<<std::endl;
    otbCastAndWriteImageMacro(TInputImageType, DoubleImageType, m_DoubleWriter);
    break;
    }
    }
}

template <class TInputVectorImageType>
void
OutputImageParameter::SwitchVectorImageWrite()
  {
  switch(m_PixelType )
    {
    case ImagePixelType_int8:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, Int8VectorImageType, m_VectorInt8Writer);
    break;
    }
    case ImagePixelType_uint8:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, UInt8VectorImageType, m_VectorUInt8Writer);
    break;
    }
    case ImagePixelType_int16:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, Int16VectorImageType, m_VectorInt16Writer);
    break;
    }
    case ImagePixelType_uint16:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, UInt16VectorImageType, m_VectorUInt16Writer);
    break;
    }
    case ImagePixelType_int32:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, Int32VectorImageType, m_VectorInt32Writer);
    break;
    }
    case ImagePixelType_uint32:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, UInt32VectorImageType, m_VectorUInt32Writer);
    break;
    }
    case ImagePixelType_float:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, FloatVectorImageType, m_VectorFloatWriter);
    break;
    }
    case ImagePixelType_double:
    {
    otbCastAndWriteImageMacro(TInputVectorImageType, DoubleVectorImageType, m_VectorDoubleWriter);
    break;
    }
    }
  }

template <class TInputRGBAImageType>
void
OutputImageParameter::SwitchRGBAImageWrite()
  {
  switch(m_PixelType )
    {
    case ImagePixelType_int8:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, Int8RGBAImageType, m_RGBAInt8Writer);
    break;
    }
    case ImagePixelType_uint8:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, UInt8RGBAImageType, m_RGBAUInt8Writer);
    break;
    }
    case ImagePixelType_int16:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, Int16RGBAImageType, m_RGBAInt16Writer);
    break;
    }
    case ImagePixelType_uint16:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, UInt16RGBAImageType, m_RGBAUInt16Writer);
    break;
    }
    case ImagePixelType_int32:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, Int32RGBAImageType, m_RGBAInt32Writer);
    break;
    }
    case ImagePixelType_uint32:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, UInt32RGBAImageType, m_RGBAUInt32Writer);
    break;
    }
    case ImagePixelType_float:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, FloatRGBAImageType, m_RGBAFloatWriter);
    break;
    }
    case ImagePixelType_double:
    {
    otbCastAndWriteImageMacro(TInputRGBAImageType, DoubleRGBAImageType, m_RGBADoubleWriter);
    break;
    }
    }
  }

void
OutputImageParameter::Write()
{
  m_Image->UpdateOutputInformation();

  if (dynamic_cast<Int8ImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<Int8ImageType>();
    }
  else if (dynamic_cast<UInt8ImageType*>(m_Image.GetPointer()))
    {
    std::cout<<"Write, input is image uint8"<<std::endl;
    SwitchImageWrite<UInt8ImageType>();
    }
  else if (dynamic_cast<Int16ImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<Int16ImageType>();
    }
  else if (dynamic_cast<UInt16ImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<UInt16ImageType>();
    }
  else if (dynamic_cast<Int32ImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<Int32ImageType>();
    }
  else if (dynamic_cast<UInt32ImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<UInt32ImageType>();
    }
  else if (dynamic_cast<FloatImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<FloatImageType>();
    }
  else if (dynamic_cast<DoubleImageType*>(m_Image.GetPointer()))
    {
    SwitchImageWrite<DoubleImageType>();
    }
  else if (dynamic_cast<Int8VectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<Int8VectorImageType>();
    }
  else if (dynamic_cast<UInt8VectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<UInt8VectorImageType>();
    }
  else if (dynamic_cast<Int16VectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<Int16VectorImageType>();
    }
  else if (dynamic_cast<UInt16VectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<UInt16VectorImageType>();
    }
  else if (dynamic_cast<Int32VectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<Int32VectorImageType>();
    }
  else if (dynamic_cast<UInt32VectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<UInt32VectorImageType>();
    }
  else if (dynamic_cast<FloatVectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<FloatVectorImageType>();
    }
  else if (dynamic_cast<DoubleVectorImageType*>(m_Image.GetPointer()))
    {
    SwitchVectorImageWrite<DoubleVectorImageType>();
    }
  else if (dynamic_cast<Int8ImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<Int8RGBAImageType>();
    }
  else if (dynamic_cast<UInt8RGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<UInt8RGBAImageType>();
    }
  else if (dynamic_cast<Int16RGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<Int16RGBAImageType>();
    }
  else if (dynamic_cast<UInt16RGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<UInt16RGBAImageType>();
    }
  else if (dynamic_cast<Int32RGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<Int32RGBAImageType>();
    }
  else if (dynamic_cast<UInt32RGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<UInt32RGBAImageType>();
    }
  else if (dynamic_cast<FloatRGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<FloatRGBAImageType>();
    }
  else if (dynamic_cast<DoubleRGBAImageType*>(m_Image.GetPointer()))
    {
    SwitchRGBAImageWrite<DoubleRGBAImageType>();
    }
  else
    {
    itkExceptionMacro("Unknown image type");
    }
  }

itk::ProcessObject*
OutputImageParameter::GetWriter()
{
  int type = 0;
  // 0 : image
  // 1 : VectorImage
  // 2 : RGBAImage

  if ( dynamic_cast<Int8VectorImageType*>(  m_Image.GetPointer()) ||
       dynamic_cast<UInt8VectorImageType*>( m_Image.GetPointer()) ||
       dynamic_cast<Int16VectorImageType*>( m_Image.GetPointer()) ||
       dynamic_cast<UInt16VectorImageType*>(m_Image.GetPointer()) ||
       dynamic_cast<Int32VectorImageType*>( m_Image.GetPointer()) ||
       dynamic_cast<UInt32VectorImageType*>(m_Image.GetPointer()) ||
       dynamic_cast<FloatVectorImageType*>( m_Image.GetPointer()) ||
       dynamic_cast<DoubleVectorImageType*>(m_Image.GetPointer())   )
    {
    type = 1;
    }
  else if( dynamic_cast<Int8RGBAImageType*>(  m_Image.GetPointer()) ||
           dynamic_cast<UInt8RGBAImageType*>( m_Image.GetPointer()) ||
           dynamic_cast<Int16RGBAImageType*>( m_Image.GetPointer()) ||
           dynamic_cast<UInt16RGBAImageType*>(m_Image.GetPointer()) ||
           dynamic_cast<Int32RGBAImageType*>( m_Image.GetPointer()) ||
           dynamic_cast<UInt32RGBAImageType*>(m_Image.GetPointer()) ||
           dynamic_cast<FloatRGBAImageType*>( m_Image.GetPointer()) ||
           dynamic_cast<DoubleRGBAImageType*>(m_Image.GetPointer())   )
    {
    type = 2;
    }

  itk::ProcessObject* writer = 0;
  switch ( GetPixelType() )
    {
    case ImagePixelType_int8:
    {
    if( type == 1 )
      writer = m_VectorInt8Writer;
    else if(type == 0)
      writer = m_Int8Writer;
    else
      writer = m_RGBAInt8Writer;
    break;
    }
    case ImagePixelType_uint8:
    {
    if( type == 1 )
      writer = m_VectorUInt8Writer;
    else if(type == 0)
      writer = m_UInt8Writer;
    else
      writer = m_RGBAUInt8Writer;
    break;
    }
    case ImagePixelType_int16:
    {
    if( type == 1 )
      writer = m_VectorInt16Writer;
    else if(type == 0)
      writer = m_Int16Writer;
    else
      writer = m_RGBAInt16Writer;
    break;
    }
    case ImagePixelType_uint16:
    {
    if( type == 1 )
      writer = m_VectorUInt16Writer;
    else if(type == 0)
      writer = m_UInt16Writer;
    else
      writer = m_RGBAUInt16Writer;
    break;
    }
    case ImagePixelType_int32:
    {
    if( type == 1 )
      writer = m_VectorInt32Writer;
    else if(type == 0)
      writer = m_Int32Writer;
    else
      writer = m_RGBAInt32Writer;
    break;
    }
    case ImagePixelType_uint32:
    {
    if( type == 1 )
      writer = m_VectorUInt32Writer;
    else if(type == 0)
      writer = m_UInt32Writer;
    else
      writer = m_RGBAUInt32Writer;
    break;
    }
    case ImagePixelType_float:
    {
    if( type == 1 )
      writer = m_VectorFloatWriter;
    else if(type == 0)
      writer = m_FloatWriter;
    else
      writer = m_RGBAFloatWriter;
    break;
    }
    case ImagePixelType_double:
    {
    if( type == 1 )
      writer = m_VectorDoubleWriter;
    else if(type == 0)
      writer = m_DoubleWriter;
    else
      writer = m_RGBADoubleWriter;
    break;
    }
    }
  return writer;
}

OutputImageParameter::ImageBaseType*
OutputImageParameter::GetValue( )
{
  return m_Image;
}

void
OutputImageParameter::SetValue(ImageBaseType* image)
{
  m_Image = image;
  SetActive(true);
}

bool
OutputImageParameter::HasValue() const
{
  std::string filename(this->GetFileName());
  return !filename.empty();
}

}
}
<|endoftext|>


<commit_before>#include <xiot/X3DFIEncodingAlgorithms.h>

#include <iostream>
#include <cmath>

#include "zlib.h"

#include <xiot/FITypes.h>
#include <xiot/FIConstants.h>
#include <xiot/X3DParseException.h>
#include <xiot/X3DFICompressionTools.h>

namespace XIOT {

	std::string QuantizedzlibFloatArrayAlgorithm::decodeToString(const FI::NonEmptyOctetString &octets) const
	{
		std::vector<float> floatArray;
		QuantizedzlibFloatArrayAlgorithm::decodeToFloatArray(octets, floatArray);

		std::stringstream ss;
		std::vector<float>::const_iterator I;
		for(I = floatArray.begin(); I != floatArray.end() -1; I++)
		{
			ss << (*I) << " ";
		}
		ss << (*I);
		return ss.str();
	}

	void QuantizedzlibFloatArrayAlgorithm::decodeToFloatArray(const FI::NonEmptyOctetString &octets, std::vector<float> &vec)
	{
    // The format for encoding the custom float format is : (-S)000EEEE|000MMMMM.
    bool sign = !static_cast<bool>(octets[0] & 0x80);
    unsigned char exponent = octets[0] & FI::Constants::LAST_FOUR_BITS;
		unsigned char mantissa = octets[1]  & FI::Constants::LAST_FIVE_BITS;

    int numBits = exponent + mantissa + (sign ? 1 : 0);

		const unsigned char* pStr = &octets.front();

		unsigned int len = FI::Tools::readUInt(pStr+2);
		unsigned int numFloats = FI::Tools::readUInt(pStr+6); // = (len * 8) / (exponent + mantissa + sign);

		std::vector<Bytef> temp_result(len);
    uLong sourceLen = static_cast<uLong>(octets.size()-10);
		uLong destSize = static_cast<uLong>(temp_result.size());

    int result_code = uncompress(&temp_result.front(), &destSize, (unsigned char*)pStr + 10, sourceLen);
    if (result_code != Z_OK) {
      std::stringstream ss;
      ss << "Error while decoding QuantizedzlibFloatArray. ZLIB error code: " << result_code;
      throw X3DParseException(ss.str());
    }

		std::vector<float> result(numFloats);

		FITools::BitUnpacker bu(&temp_result.front(), destSize);
		FITools::FloatPacker fp(exponent, mantissa);
		for(unsigned int i=0; i < numFloats; i++) {
			unsigned long val = bu.unpack(numBits);
			result[i] = fp.decode(val, sign);
		}
		std::swap(result, vec);
	}

	void QuantizedzlibFloatArrayAlgorithm::encode(const float* values, size_t size, FI::NonEmptyOctetString &octets)
	{
		unsigned char* bytes = new unsigned char[size*4];
		unsigned char* bytepos = bytes;
		size_t i;

		const float* vf = values;
		for (i = 0; i < size; i++)
		{
			union float_to_unsigned_int_to_bytes
			{
				float f;
				unsigned int ui;
				unsigned char ub[4]; // unsigned bytes
			};
			float_to_unsigned_int_to_bytes v;
			v.f = (*vf) * 2.0f;

			// Avoid -0
			if (v.ui == 0x80000000)
			{
				v.f = 0.0f;
			}
			// std::cout << "value: " << v << " bytes: " << (int)s[0] << " " << (int)s[1] << " " << (int)s[2] << " " << (int)s[3]) << std::endl;
			*bytepos++ = v.ub[3];
			*bytepos++ = v.ub[2];
			*bytepos++ = v.ub[1];
			*bytepos++ = v.ub[0];
			vf++;
		}

		// Compress the data
		unsigned long compressedSize = static_cast<unsigned long>(size*4) + static_cast<unsigned long>(ceil((size*4)*0.001)) + 12;
		Bytef* compressedData = new Bytef[compressedSize];

		// Call zlib's compress function.
		if(compress2(compressedData, &compressedSize, reinterpret_cast<const Bytef*>(bytes), static_cast<unsigned long>(size*4), Z_DEFAULT_COMPRESSION) != Z_OK)
		{
			throw X3DParseException("Error while encoding QuantizedzlibFloatArrayAlgorithm");
		}

		unsigned char *s;
		// Put the number of bits for exponent
    octets.push_back(static_cast<unsigned char>(8));
		// Put the number of bits for mantissa
    octets.push_back(static_cast<unsigned char>(23));

		// Put the length
		int length = static_cast<int>(size*4);
		int length_reversed = FI::Tools::reverseBytes(&length);
		s = reinterpret_cast <unsigned char*> (&length_reversed);
    octets.insert(octets.end(), s, s+3);

		// Put the number of floats
		int numFloats = static_cast<int>(size);
		int numFloats_reversed = FI::Tools::reverseBytes(&numFloats);;
		s = reinterpret_cast <unsigned char*> (&numFloats_reversed);
    octets.insert(octets.end(), s, s+3);
    //octets.insert(octets.end(), s[0], s[3]);
		//octets.append(s, 4);

		for (i = 0; i < compressedSize; i++)
		{
			unsigned char c = compressedData[i];
      octets.push_back(c);
		}
		delete[] compressedData;
		delete[] bytes;
	}

	std::string DeltazlibIntArrayAlgorithm::decodeToString(const FI::NonEmptyOctetString &octets) const
	{
		std::vector<int> intArray;
		DeltazlibIntArrayAlgorithm::decodeToIntArray(octets, intArray);

		std::stringstream ss;
		std::vector<int>::const_iterator I;
		for(I = intArray.begin(); I != intArray.end() -1; I++)
		{
			ss << (*I) << " ";
		}
		ss << (*I);
		return ss.str();
	}

	void DeltazlibIntArrayAlgorithm::decodeToIntArray(const FI::NonEmptyOctetString &octets, std::vector<int> &vec)
	{
		const unsigned char* pStr = &octets.front();

		unsigned int length = FI::Tools::readUInt((unsigned char*)pStr);
		unsigned char span = octets[4];

		std::vector<Bytef> temp_result(length*4);
    uLong sourceLen = static_cast<uLong>(octets.size()-5);
		uLong destSize = static_cast<uLong>(temp_result.size());
		const Bytef *source = (const Bytef *)(pStr + 5);

    int result_code = uncompress(&temp_result.front(), &destSize, source, sourceLen);
    if (result_code != Z_OK) {
      std::stringstream ss;
      ss << "Error while decoding DeltazlibIntArrayAlgorithm. ZLIB error code: " << result_code;
      throw X3DParseException(ss.str());
    }
		std::vector<int> result(length);

		Bytef* pRes = &temp_result.front();
		for(unsigned int i = 0; i < length; i++)
		{
			result[i] = FI::Tools::readUInt(pRes) -1;
			if (span && i >= span)
				result[i] += result[i-span];
			pRes+=4;
		}
		std::swap(result, vec);
	}

	void DeltazlibIntArrayAlgorithm::encode(const int* values, size_t size, FI::NonEmptyOctetString &octets, bool isImage)
	{
		// compute delta
		char span = 0;
		size_t i = 0;
		int f; unsigned char *p;
		std::vector<unsigned char> deltas;

		if (isImage)
		{
			span = 0;
			for(i = 0; i < size; i++)
			{
				int v = 1 + (values[i]);
				int *vp = reinterpret_cast<int*>(&v);
				f = FI::Tools::reverseBytes(vp);
				p = reinterpret_cast <unsigned char*> (&f);
				deltas.push_back(p[0]);
				deltas.push_back(p[1]);
				deltas.push_back(p[2]);
				deltas.push_back(p[3]);
			}
		}
		else
		{
			for (i = 0; i < 20; i++)
			{
				if (values[i] == -1)
				{
					span = static_cast<char>(i) + 1;
					break;
				}
			}
			if (!span) span = 4;

			for(i = 0; i < static_cast<size_t>(span); i++)
			{
				int v = 1 + values[i];
				int *vp = reinterpret_cast<int*>(&v);
				f = FI::Tools::reverseBytes(vp);

				p = reinterpret_cast <unsigned char*> (&f);
				deltas.push_back(p[0]);
				deltas.push_back(p[1]);
				deltas.push_back(p[2]);
				deltas.push_back(p[3]);
			}
			for(i = span; i < size; i++)
			{
				int v = 1 + (values[i] - values[i-span]);
				f = FI::Tools::reverseBytes(&v);

				p = reinterpret_cast <unsigned char*> (&f);
				deltas.push_back(p[0]);
				deltas.push_back(p[1]);
				deltas.push_back(p[2]);
				deltas.push_back(p[3]);
			}
		}

		unsigned long compressedSize = static_cast<unsigned long>(deltas.size() + ceil(deltas.size()*0.001)) + 12;
		Bytef* compressedData = new Bytef[compressedSize];

		// Call zlib's compress function.
		if(compress2(compressedData, &compressedSize, reinterpret_cast<const Bytef*>(&deltas[0]), static_cast<unsigned long>(deltas.size()), Z_DEFAULT_COMPRESSION) != Z_OK)
		{
			throw X3DParseException("Error while encoding DeltazlibIntArrayAlgorithm");
		}

		int size32 = static_cast<int>(size);
		int size32_reversed = FI::Tools::reverseBytes(&size32);
		char *s = reinterpret_cast <char*> (&size32_reversed);

		octets.insert(octets.begin(), s, s+4);
		octets.push_back(span);

		for (i = 0; i < compressedSize; i++)
		{
			octets.push_back(compressedData[i]);
		}
		delete[] compressedData;

	}
}

<commit_msg>Fixed warning<commit_after>#include <xiot/X3DFIEncodingAlgorithms.h>

#include <iostream>
#include <cmath>

#include "zlib.h"

#include <xiot/FITypes.h>
#include <xiot/FIConstants.h>
#include <xiot/X3DParseException.h>
#include <xiot/X3DFICompressionTools.h>

namespace XIOT {

	std::string QuantizedzlibFloatArrayAlgorithm::decodeToString(const FI::NonEmptyOctetString &octets) const
	{
		std::vector<float> floatArray;
		QuantizedzlibFloatArrayAlgorithm::decodeToFloatArray(octets, floatArray);

		std::stringstream ss;
		std::vector<float>::const_iterator I;
		for(I = floatArray.begin(); I != floatArray.end() -1; I++)
		{
			ss << (*I) << " ";
		}
		ss << (*I);
		return ss.str();
	}

	void QuantizedzlibFloatArrayAlgorithm::decodeToFloatArray(const FI::NonEmptyOctetString &octets, std::vector<float> &vec)
	{
    // The format for encoding the custom float format is : (-S)000EEEE|000MMMMM.
    bool sign = (octets[0] & 0x80) == 0;
    unsigned char exponent = octets[0] & FI::Constants::LAST_FOUR_BITS;
		unsigned char mantissa = octets[1]  & FI::Constants::LAST_FIVE_BITS;

    int numBits = exponent + mantissa + (sign ? 1 : 0);

		const unsigned char* pStr = &octets.front();

		unsigned int len = FI::Tools::readUInt(pStr+2);
		unsigned int numFloats = FI::Tools::readUInt(pStr+6); // = (len * 8) / (exponent + mantissa + sign);

		std::vector<Bytef> temp_result(len);
    uLong sourceLen = static_cast<uLong>(octets.size()-10);
		uLong destSize = static_cast<uLong>(temp_result.size());

    int result_code = uncompress(&temp_result.front(), &destSize, (unsigned char*)pStr + 10, sourceLen);
    if (result_code != Z_OK) {
      std::stringstream ss;
      ss << "Error while decoding QuantizedzlibFloatArray. ZLIB error code: " << result_code;
      throw X3DParseException(ss.str());
    }

		std::vector<float> result(numFloats);

		FITools::BitUnpacker bu(&temp_result.front(), destSize);
		FITools::FloatPacker fp(exponent, mantissa);
		for(unsigned int i=0; i < numFloats; i++) {
			unsigned long val = bu.unpack(numBits);
			result[i] = fp.decode(val, sign);
		}
		std::swap(result, vec);
	}

	void QuantizedzlibFloatArrayAlgorithm::encode(const float* values, size_t size, FI::NonEmptyOctetString &octets)
	{
		unsigned char* bytes = new unsigned char[size*4];
		unsigned char* bytepos = bytes;
		size_t i;

		const float* vf = values;
		for (i = 0; i < size; i++)
		{
			union float_to_unsigned_int_to_bytes
			{
				float f;
				unsigned int ui;
				unsigned char ub[4]; // unsigned bytes
			};
			float_to_unsigned_int_to_bytes v;
			v.f = (*vf) * 2.0f;

			// Avoid -0
			if (v.ui == 0x80000000)
			{
				v.f = 0.0f;
			}
			// std::cout << "value: " << v << " bytes: " << (int)s[0] << " " << (int)s[1] << " " << (int)s[2] << " " << (int)s[3]) << std::endl;
			*bytepos++ = v.ub[3];
			*bytepos++ = v.ub[2];
			*bytepos++ = v.ub[1];
			*bytepos++ = v.ub[0];
			vf++;
		}

		// Compress the data
		unsigned long compressedSize = static_cast<unsigned long>(size*4) + static_cast<unsigned long>(ceil((size*4)*0.001)) + 12;
		Bytef* compressedData = new Bytef[compressedSize];

		// Call zlib's compress function.
		if(compress2(compressedData, &compressedSize, reinterpret_cast<const Bytef*>(bytes), static_cast<unsigned long>(size*4), Z_DEFAULT_COMPRESSION) != Z_OK)
		{
			throw X3DParseException("Error while encoding QuantizedzlibFloatArrayAlgorithm");
		}

		unsigned char *s;
		// Put the number of bits for exponent
    octets.push_back(static_cast<unsigned char>(8));
		// Put the number of bits for mantissa
    octets.push_back(static_cast<unsigned char>(23));

		// Put the length
		int length = static_cast<int>(size*4);
		int length_reversed = FI::Tools::reverseBytes(&length);
		s = reinterpret_cast <unsigned char*> (&length_reversed);
    octets.insert(octets.end(), s, s+3);

		// Put the number of floats
		int numFloats = static_cast<int>(size);
		int numFloats_reversed = FI::Tools::reverseBytes(&numFloats);;
		s = reinterpret_cast <unsigned char*> (&numFloats_reversed);
    octets.insert(octets.end(), s, s+3);
    //octets.insert(octets.end(), s[0], s[3]);
		//octets.append(s, 4);

		for (i = 0; i < compressedSize; i++)
		{
			unsigned char c = compressedData[i];
      octets.push_back(c);
		}
		delete[] compressedData;
		delete[] bytes;
	}

	std::string DeltazlibIntArrayAlgorithm::decodeToString(const FI::NonEmptyOctetString &octets) const
	{
		std::vector<int> intArray;
		DeltazlibIntArrayAlgorithm::decodeToIntArray(octets, intArray);

		std::stringstream ss;
		std::vector<int>::const_iterator I;
		for(I = intArray.begin(); I != intArray.end() -1; I++)
		{
			ss << (*I) << " ";
		}
		ss << (*I);
		return ss.str();
	}

	void DeltazlibIntArrayAlgorithm::decodeToIntArray(const FI::NonEmptyOctetString &octets, std::vector<int> &vec)
	{
		const unsigned char* pStr = &octets.front();

		unsigned int length = FI::Tools::readUInt((unsigned char*)pStr);
		unsigned char span = octets[4];

		std::vector<Bytef> temp_result(length*4);
    uLong sourceLen = static_cast<uLong>(octets.size()-5);
		uLong destSize = static_cast<uLong>(temp_result.size());
		const Bytef *source = (const Bytef *)(pStr + 5);

    int result_code = uncompress(&temp_result.front(), &destSize, source, sourceLen);
    if (result_code != Z_OK) {
      std::stringstream ss;
      ss << "Error while decoding DeltazlibIntArrayAlgorithm. ZLIB error code: " << result_code;
      throw X3DParseException(ss.str());
    }
		std::vector<int> result(length);

		Bytef* pRes = &temp_result.front();
		for(unsigned int i = 0; i < length; i++)
		{
			result[i] = FI::Tools::readUInt(pRes) -1;
			if (span && i >= span)
				result[i] += result[i-span];
			pRes+=4;
		}
		std::swap(result, vec);
	}

	void DeltazlibIntArrayAlgorithm::encode(const int* values, size_t size, FI::NonEmptyOctetString &octets, bool isImage)
	{
		// compute delta
		char span = 0;
		size_t i = 0;
		int f; unsigned char *p;
		std::vector<unsigned char> deltas;

		if (isImage)
		{
			span = 0;
			for(i = 0; i < size; i++)
			{
				int v = 1 + (values[i]);
				int *vp = reinterpret_cast<int*>(&v);
				f = FI::Tools::reverseBytes(vp);
				p = reinterpret_cast <unsigned char*> (&f);
				deltas.push_back(p[0]);
				deltas.push_back(p[1]);
				deltas.push_back(p[2]);
				deltas.push_back(p[3]);
			}
		}
		else
		{
			for (i = 0; i < 20; i++)
			{
				if (values[i] == -1)
				{
					span = static_cast<char>(i) + 1;
					break;
				}
			}
			if (!span) span = 4;

			for(i = 0; i < static_cast<size_t>(span); i++)
			{
				int v = 1 + values[i];
				int *vp = reinterpret_cast<int*>(&v);
				f = FI::Tools::reverseBytes(vp);

				p = reinterpret_cast <unsigned char*> (&f);
				deltas.push_back(p[0]);
				deltas.push_back(p[1]);
				deltas.push_back(p[2]);
				deltas.push_back(p[3]);
			}
			for(i = span; i < size; i++)
			{
				int v = 1 + (values[i] - values[i-span]);
				f = FI::Tools::reverseBytes(&v);

				p = reinterpret_cast <unsigned char*> (&f);
				deltas.push_back(p[0]);
				deltas.push_back(p[1]);
				deltas.push_back(p[2]);
				deltas.push_back(p[3]);
			}
		}

		unsigned long compressedSize = static_cast<unsigned long>(deltas.size() + ceil(deltas.size()*0.001)) + 12;
		Bytef* compressedData = new Bytef[compressedSize];

		// Call zlib's compress function.
		if(compress2(compressedData, &compressedSize, reinterpret_cast<const Bytef*>(&deltas[0]), static_cast<unsigned long>(deltas.size()), Z_DEFAULT_COMPRESSION) != Z_OK)
		{
			throw X3DParseException("Error while encoding DeltazlibIntArrayAlgorithm");
		}

		int size32 = static_cast<int>(size);
		int size32_reversed = FI::Tools::reverseBytes(&size32);
		char *s = reinterpret_cast <char*> (&size32_reversed);

		octets.insert(octets.begin(), s, s+4);
		octets.push_back(span);

		for (i = 0; i < compressedSize; i++)
		{
			octets.push_back(compressedData[i]);
		}
		delete[] compressedData;

	}
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "helpers.h"
#include "render_to_window.h"

static VkBool32 debug_report_callback(
    VkDebugUtilsMessageSeverityFlagBitsEXT           messageSeverity,
    VkDebugUtilsMessageTypeFlagsEXT                  messageTypes,
    const VkDebugUtilsMessengerCallbackDataEXT*      pCallbackData,
    void*                                            pUserData)
{
    std::cerr << pCallbackData->pMessage << std::endl;
    return false;
}

static std::optional<vk::UniqueDebugUtilsMessengerEXT> create_debug_report_callback(vk::Instance instance)
{
#if _DEBUG
    auto info = vk::DebugUtilsMessengerCreateInfoEXT()
        .setMessageSeverity(
            vk::DebugUtilsMessageSeverityFlagBitsEXT::eError|
            vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning
        )
        .setMessageType(
            vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral|
            vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance|
            vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation
        )
    .setPfnUserCallback(debug_report_callback);

    return std::optional { instance.createDebugUtilsMessengerEXTUnique(info, nullptr) };
#else
    return std::nullopt;
#endif
}

static vk::UniqueInstance create_instance()
{
#if _DEBUG
    std::array layerNames { "VK_LAYER_KHRONOS_validation" };
#else
    std::array<const char*, 0> layerNames;
#endif

    std::array extensionNames {
#if _DEBUG
        VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
#endif
        VK_KHR_SURFACE_EXTENSION_NAME,
        VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
        VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
    };

    auto app_info = vk::ApplicationInfo().setApiVersion(VK_API_VERSION_1_1);

    return vk::createInstanceUnique(
        vk::InstanceCreateInfo()
        .setPEnabledLayerNames(layerNames)
        .setPEnabledExtensionNames(extensionNames)
        .setPApplicationInfo(&app_info)
    );
}

static vk::PhysicalDevice get_physical_device(vk::Instance vulkan)
{
    auto devices = vulkan.enumeratePhysicalDevices();
    assert(devices.size() > 0);

    auto device = devices[0];
    auto props = device.getProperties();
    std::cout << "Using physical device " << props.deviceName << std::endl;
    return device;
}

static vk::UniqueDevice create_device(vk::PhysicalDevice physical_device)
{
    auto props = physical_device.getQueueFamilyProperties();
    assert((props[0].queueFlags & vk::QueueFlagBits::eGraphics) == vk::QueueFlagBits::eGraphics);

    std::array priorities { 0.f };
    auto queueInfo = vk::DeviceQueueCreateInfo()
        .setQueuePriorities(priorities);

    std::array extensionNames {
        VK_KHR_SWAPCHAIN_EXTENSION_NAME,
        VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
        VK_NV_RAY_TRACING_EXTENSION_NAME,
    };

    auto features = vk::PhysicalDeviceFeatures()
        .setMultiDrawIndirect(true)
        .setDrawIndirectFirstInstance(true)
        .setShaderClipDistance(true)
        .setShaderCullDistance(true);

    return physical_device.createDeviceUnique(
        vk::DeviceCreateInfo()
        .setQueueCreateInfoCount(1)
        .setPQueueCreateInfos(&queueInfo)
        .setPEnabledExtensionNames(extensionNames)
        .setPEnabledFeatures(&features)
    );
}

glm::vec3 std_vector_to_glm_vec3(const std::vector<float>& vector)
{
    return glm::vec3(vector[0], vector[1], vector[2]);
}

VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE

int main(int argc, char** argv)
{
    cxxopts::Options options("VulkanRenderer", "Vulkan renderer");
    options.add_options()
        ("model", "PLY model to render. File dialog will be shown if ommitted.", cxxopts::value<std::string>(), "path")
        ("image", "PNG image to save rendering to (overwrites existing). No window will be created if specified.", cxxopts::value<std::string>(), "path")
        ("camera_position", "When using --image, specifies the camera position.", cxxopts::value<std::vector<float>>(), "x y z")
        ("camera_up", "When using --image, specifies the camera up vector.", cxxopts::value<std::vector<float>>(), "x y z")
        ("help", "Show help")
        ;

    cxxopts::ParseResult result = options.parse(argc, argv);

    if (result["help"].count() > 0) {
        std::cout << options.help();
        return EXIT_SUCCESS;
    }

    std::string model_path;
    auto model_path_option = result["model"];

    if (model_path_option.count() == 1)
    {
        model_path = model_path_option.as<std::string>();
    }
    else
    {
        auto pattern = "*.ply";
        auto model_path_ptr = tinyfd_openFileDialog("Open 3D model", nullptr, 1, &pattern, nullptr, 0);
        if (!model_path_ptr)
        {
            return EXIT_FAILURE;
        }
        model_path = model_path_ptr;
    }

    vk::DynamicLoader dl;
    VULKAN_HPP_DEFAULT_DISPATCHER.init(dl.getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr"));

    auto instance = create_instance();
    VULKAN_HPP_DEFAULT_DISPATCHER.init(instance.get());

    auto callback = create_debug_report_callback(instance.get());
    auto physical_device = get_physical_device(instance.get());

    auto device = create_device(physical_device);
    VULKAN_HPP_DEFAULT_DISPATCHER.init(device.get());

    auto image_path_option = result["image"];
    if (image_path_option.count() == 1)
    {
        auto camera_position_option = result["camera_position"];
        auto camera_position = camera_position_option.count() == 3
            ? std_vector_to_glm_vec3(camera_position_option.as<std::vector<float>>())
            : glm::vec3(0.f, 0.f, 2.f);

        auto camera_up_vector = result["camera_up"];
        auto camera_up = camera_up_vector.count() == 3
            ? std_vector_to_glm_vec3(camera_up_vector.as<std::vector<float>>())
            : glm::vec3(0.f, -1.f, 0.f);

        std::cout << "Rendering to image..." << std::endl;
        render_to_image(physical_device, device.get(), model_path, image_path_option.as<std::string>(), camera_position, camera_up);
    }
    else
    {
        std::cout << "Rendering to window..." << std::endl;
        render_to_window(instance.get(), physical_device, device.get(), model_path);
    }

    return EXIT_SUCCESS;
}
<commit_msg>Make validation messages more readable<commit_after>#include "stdafx.h"
#include "helpers.h"
#include "render_to_window.h"

static VkBool32 debug_report_callback(
    VkDebugUtilsMessageSeverityFlagBitsEXT           messageSeverity,
    VkDebugUtilsMessageTypeFlagsEXT                  messageTypes,
    const VkDebugUtilsMessengerCallbackDataEXT*      pCallbackData,
    void*                                            pUserData)
{
    std::cerr << pCallbackData->pMessage << std::endl << std::endl;
    return false;
}

static std::optional<vk::UniqueDebugUtilsMessengerEXT> create_debug_report_callback(vk::Instance instance)
{
#if _DEBUG
    auto info = vk::DebugUtilsMessengerCreateInfoEXT()
        .setMessageSeverity(
            vk::DebugUtilsMessageSeverityFlagBitsEXT::eError|
            vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning
        )
        .setMessageType(
            vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral|
            vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance|
            vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation
        )
    .setPfnUserCallback(debug_report_callback);

    return std::optional { instance.createDebugUtilsMessengerEXTUnique(info, nullptr) };
#else
    return std::nullopt;
#endif
}

static vk::UniqueInstance create_instance()
{
#if _DEBUG
    std::array layerNames { "VK_LAYER_KHRONOS_validation" };
#else
    std::array<const char*, 0> layerNames;
#endif

    std::array extensionNames {
#if _DEBUG
        VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
#endif
        VK_KHR_SURFACE_EXTENSION_NAME,
        VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
        VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
    };

    auto app_info = vk::ApplicationInfo().setApiVersion(VK_API_VERSION_1_1);

    return vk::createInstanceUnique(
        vk::InstanceCreateInfo()
        .setPEnabledLayerNames(layerNames)
        .setPEnabledExtensionNames(extensionNames)
        .setPApplicationInfo(&app_info)
    );
}

static vk::PhysicalDevice get_physical_device(vk::Instance vulkan)
{
    auto devices = vulkan.enumeratePhysicalDevices();
    assert(devices.size() > 0);

    auto device = devices[0];
    auto props = device.getProperties();
    std::cout << "Using physical device " << props.deviceName << std::endl;
    return device;
}

static vk::UniqueDevice create_device(vk::PhysicalDevice physical_device)
{
    auto props = physical_device.getQueueFamilyProperties();
    assert((props[0].queueFlags & vk::QueueFlagBits::eGraphics) == vk::QueueFlagBits::eGraphics);

    std::array priorities { 0.f };
    auto queueInfo = vk::DeviceQueueCreateInfo()
        .setQueuePriorities(priorities);

    std::array extensionNames {
        VK_KHR_SWAPCHAIN_EXTENSION_NAME,
        VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
        VK_NV_RAY_TRACING_EXTENSION_NAME,
    };

    auto features = vk::PhysicalDeviceFeatures()
        .setMultiDrawIndirect(true)
        .setDrawIndirectFirstInstance(true)
        .setShaderClipDistance(true)
        .setShaderCullDistance(true);

    return physical_device.createDeviceUnique(
        vk::DeviceCreateInfo()
        .setQueueCreateInfoCount(1)
        .setPQueueCreateInfos(&queueInfo)
        .setPEnabledExtensionNames(extensionNames)
        .setPEnabledFeatures(&features)
    );
}

glm::vec3 std_vector_to_glm_vec3(const std::vector<float>& vector)
{
    return glm::vec3(vector[0], vector[1], vector[2]);
}

VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE

int main(int argc, char** argv)
{
    cxxopts::Options options("VulkanRenderer", "Vulkan renderer");
    options.add_options()
        ("model", "PLY model to render. File dialog will be shown if ommitted.", cxxopts::value<std::string>(), "path")
        ("image", "PNG image to save rendering to (overwrites existing). No window will be created if specified.", cxxopts::value<std::string>(), "path")
        ("camera_position", "When using --image, specifies the camera position.", cxxopts::value<std::vector<float>>(), "x y z")
        ("camera_up", "When using --image, specifies the camera up vector.", cxxopts::value<std::vector<float>>(), "x y z")
        ("help", "Show help")
        ;

    cxxopts::ParseResult result = options.parse(argc, argv);

    if (result["help"].count() > 0) {
        std::cout << options.help();
        return EXIT_SUCCESS;
    }

    std::string model_path;
    auto model_path_option = result["model"];

    if (model_path_option.count() == 1)
    {
        model_path = model_path_option.as<std::string>();
    }
    else
    {
        auto pattern = "*.ply";
        auto model_path_ptr = tinyfd_openFileDialog("Open 3D model", nullptr, 1, &pattern, nullptr, 0);
        if (!model_path_ptr)
        {
            return EXIT_FAILURE;
        }
        model_path = model_path_ptr;
    }

    vk::DynamicLoader dl;
    VULKAN_HPP_DEFAULT_DISPATCHER.init(dl.getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr"));

    auto instance = create_instance();
    VULKAN_HPP_DEFAULT_DISPATCHER.init(instance.get());

    auto callback = create_debug_report_callback(instance.get());
    auto physical_device = get_physical_device(instance.get());

    auto device = create_device(physical_device);
    VULKAN_HPP_DEFAULT_DISPATCHER.init(device.get());

    auto image_path_option = result["image"];
    if (image_path_option.count() == 1)
    {
        auto camera_position_option = result["camera_position"];
        auto camera_position = camera_position_option.count() == 3
            ? std_vector_to_glm_vec3(camera_position_option.as<std::vector<float>>())
            : glm::vec3(0.f, 0.f, 2.f);

        auto camera_up_vector = result["camera_up"];
        auto camera_up = camera_up_vector.count() == 3
            ? std_vector_to_glm_vec3(camera_up_vector.as<std::vector<float>>())
            : glm::vec3(0.f, -1.f, 0.f);

        std::cout << "Rendering to image..." << std::endl;
        render_to_image(physical_device, device.get(), model_path, image_path_option.as<std::string>(), camera_position, camera_up);
    }
    else
    {
        std::cout << "Rendering to window..." << std::endl;
        render_to_window(instance.get(), physical_device, device.get(), model_path);
    }

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011, Cornell University
// 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.
//     * Neither the name of HyperDex nor the names of its contributors may be
//       used to endorse or promote products derived from this software without
//       specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.

// Google Test
#include <gtest/gtest.h>

// HyperDex
#include <hyperdex/query.h>

#pragma GCC diagnostic ignored "-Wswitch-default"

namespace
{

// Create and destroy queries of various sizes.
TEST(QueryTest, CtorAndDtor)
{
    for (size_t i = 0; i < 65536; ++i)
    {
        hyperdex::query q(i);
    }
}

// Create a query and set/unset the values while testing that it still matches
// the row.
TEST(QueryTest, SetAndUnset)
{
    hyperdex::query q(10);
    std::vector<std::string> row(10, "value");

    for (size_t i = 0; i < 10; ++i)
    {
        EXPECT_TRUE(q.matches(row));
        q.set(i, "value");
    }

    EXPECT_TRUE(q.matches(row));

    for (size_t i = 0; i < 10; ++i)
    {
        EXPECT_TRUE(q.matches(row));
        q.set(i, "value");
    }

    EXPECT_TRUE(q.matches(row));
}

TEST(QueryTest, Clear)
{
    hyperdex::query q(2);
    std::vector<std::string> r;

    r.push_back("key");
    r.push_back("val");
    EXPECT_TRUE(q.matches(r));
    q.set(0, "not-key");
    q.set(1, "not-val");
    EXPECT_FALSE(q.matches(r));
    q.clear();
    EXPECT_TRUE(q.matches(r));
}

// Test non-matches
TEST(QueryTest, NegativeMatch)
{
    hyperdex::query q(2);
    std::vector<std::string> r;

    r.push_back("key");
    r.push_back("val");
    EXPECT_TRUE(q.matches(r));
    q.set(0, "not-key");
    EXPECT_FALSE(q.matches(r));
    q.unset(0);
    EXPECT_TRUE(q.matches(r));
    q.set(1, "not-val");
    EXPECT_FALSE(q.matches(r));
}

// If we try to set out of bounds we fail an assertion.
TEST(QueryTest, SetDeathTest)
{
    hyperdex::query q(5);

    ASSERT_DEATH(
        q.set(5, "out of bounds");
    , "Assertion");
}

// If we try to unset out of bounds we fail an assertion.
TEST(QueryTest, UnsetDeathTest)
{
    hyperdex::query q(5);

    ASSERT_DEATH(
        q.unset(5);
    , "Assertion");
}

// If we try to match with improper arity we fail an assertion.
TEST(QueryTest, MatchDeathTest)
{
    hyperdex::query q(5);

    ASSERT_DEATH(
        q.matches(std::vector<std::string>(4));
    , "Assertion");
}

} // namespace
<commit_msg>Cut down the runtime of the QueryTest cases.<commit_after>// Copyright (c) 2011, Cornell University
// 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.
//     * Neither the name of HyperDex nor the names of its contributors may be
//       used to endorse or promote products derived from this software without
//       specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.

// Google Test
#include <gtest/gtest.h>

// HyperDex
#include <hyperdex/query.h>

#pragma GCC diagnostic ignored "-Wswitch-default"

namespace
{

// Create and destroy queries of various sizes.
TEST(QueryTest, CtorAndDtor)
{
    for (size_t i = 1; i < 65536; i *= 2)
    {
        hyperdex::query q(i);
    }
}

// Create a query and set/unset the values while testing that it still matches
// the row.
TEST(QueryTest, SetAndUnset)
{
    hyperdex::query q(10);
    std::vector<std::string> row(10, "value");

    for (size_t i = 0; i < 10; ++i)
    {
        EXPECT_TRUE(q.matches(row));
        q.set(i, "value");
    }

    EXPECT_TRUE(q.matches(row));

    for (size_t i = 0; i < 10; ++i)
    {
        EXPECT_TRUE(q.matches(row));
        q.set(i, "value");
    }

    EXPECT_TRUE(q.matches(row));
}

TEST(QueryTest, Clear)
{
    hyperdex::query q(2);
    std::vector<std::string> r;

    r.push_back("key");
    r.push_back("val");
    EXPECT_TRUE(q.matches(r));
    q.set(0, "not-key");
    q.set(1, "not-val");
    EXPECT_FALSE(q.matches(r));
    q.clear();
    EXPECT_TRUE(q.matches(r));
}

// Test non-matches
TEST(QueryTest, NegativeMatch)
{
    hyperdex::query q(2);
    std::vector<std::string> r;

    r.push_back("key");
    r.push_back("val");
    EXPECT_TRUE(q.matches(r));
    q.set(0, "not-key");
    EXPECT_FALSE(q.matches(r));
    q.unset(0);
    EXPECT_TRUE(q.matches(r));
    q.set(1, "not-val");
    EXPECT_FALSE(q.matches(r));
}

// If we try to set out of bounds we fail an assertion.
TEST(QueryTest, SetDeathTest)
{
    hyperdex::query q(5);

    ASSERT_DEATH(
        q.set(5, "out of bounds");
    , "Assertion");
}

// If we try to unset out of bounds we fail an assertion.
TEST(QueryTest, UnsetDeathTest)
{
    hyperdex::query q(5);

    ASSERT_DEATH(
        q.unset(5);
    , "Assertion");
}

// If we try to match with improper arity we fail an assertion.
TEST(QueryTest, MatchDeathTest)
{
    hyperdex::query q(5);

    ASSERT_DEATH(
        q.matches(std::vector<std::string>(4));
    , "Assertion");
}

} // namespace
<|endoftext|>