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

  Copyright (c) Kitware Inc. All rights reserved.
  See Copyright.txt or http://www.Kitware.com/Copyright.htm for details.

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

=========================================================================*/

#include "midasCLI.h"
#include "midasDotProgressReporter.h"

midasCLI::midasCLI()
{
  this->Synchronizer = new midasSynchronizer();
  this->Synchronizer->SetDatabase(
    kwsys::SystemTools::GetCurrentWorkingDirectory() + "/midas.db");
  this->Synchronizer->SetProgressReporter(
    reinterpret_cast<midasProgressReporter*>(
    new midasDotProgressReporter(30)));
}

midasCLI::~midasCLI()
{
  this->Synchronizer->DeleteProgressReporter();
  delete this->Synchronizer;
}

//-------------------------------------------------------------------
int midasCLI::Perform(std::vector<std::string> args)
{
  if(args.size() == 0)
    {
    this->PrintUsage();
    return -1;
    }

  bool ok = false;

  for(unsigned i = 0; i < args.size(); i++)
    {
    if(args[i] == "add")
      {
      std::vector<std::string> postOpArgs(args.begin() + i + 1, args.end());
      ok = this->ParseAdd(postOpArgs);
      break;
      }
    else if(args[i] == "clean")
      {
      std::vector<std::string> postOpArgs(args.begin() + i + 1, args.end());
      ok = this->ParseClean(postOpArgs);
      break;
      }
    else if(args[i] == "clone")
      {
      std::vector<std::string> postOpArgs(args.begin() + i + 1, args.end());
      ok = this->ParseClone(postOpArgs);
      break;
      }
    else if(args[i] == "create_profile")
      {
      std::vector<std::string> postOpArgs(args.begin() + i + 1, args.end());
      return this->PerformCreateProfile(postOpArgs);
      }
    else if(args[i] == "push")
      {
      std::vector<std::string> postOpArgs(args.begin() + i + 1, args.end());
      ok = this->ParsePush(postOpArgs);
      break;
      }
    else if(args[i] == "pull")
      {
      std::vector<std::string> postOpArgs(args.begin() + i + 1, args.end());
      ok = this->ParsePull(postOpArgs);
      break;
      }
    else if(args[i] == "--database" && i + 1 < args.size())
      {
      i++;
      this->Synchronizer->SetDatabase(args[i]);
      }
    else if(args[i] == "--profile" && i + 1 < args.size())
      {
      i++;
      this->Synchronizer->GetAuthenticator()->SetProfile(args[i]);
      }
    else if(args[i] == "--help")
      {
      if(i + 2 < args.size())
        {
        i++;
        this->PrintCommandHelp(args[i]);
        }
      else
        {
        this->PrintUsage();
        }
      return 0;
      }
    else
      {
      this->PrintUsage();
      return -1;
      }
    }
  return ok ? this->Synchronizer->Perform() : -1;
}

//-------------------------------------------------------------------
int midasCLI::PerformCreateProfile(std::vector<std::string> args)
{
  unsigned i;

  std::string name, user, apiKey, appName;
  for(i = 0; i < args.size(); i++)
    {
    if(args[i] == "-u" || args[i] == "--email"
      && args.size() > i + 1)
      {
      i++;
      user = args[i];
      }
    else if(args[i] == "-n" || args[i] == "--name"
      && args.size() > i + 1)
      {
      i++;
      name = args[i];
      }
    else if(args[i] == "-k" || args[i] == "--api-key"
      && args.size() > i + 1)
      {
      i++;
      apiKey = args[i];
      }
    else if(args[i] == "-a" || args[i] == "--app-name"
      && args.size() > i + 1)
      {
      i++;
      appName = args[i];
      }
    else
      {
      this->Synchronizer->SetServerURL(args[i]);
      }
    }

  if(name == "" || user == "" || apiKey == "" || appName == "")
    {
    this->PrintCommandHelp("create_profile");
    return -1;
    }

  this->

  std::cout << "Adding authentication profile '" << name << "'" << std::endl;
  bool ok = this->Synchronizer->GetAuthenticator()->AddAuthProfile(
    user, appName, apiKey, name);

  if(ok)
    {
    std::cout << "Profile successfully created." << std::endl;
    return 0;
    }
  else
    {
    std::cout << "Failed to add authentication profile." << std::endl;
    return -1;
    }
}

//-------------------------------------------------------------------
bool midasCLI::ParseAdd(std::vector<std::string> args)
{
  this->Synchronizer->SetOperation(midasSynchronizer::OPERATION_ADD);

  unsigned i;
  for(i = 0; i < args.size(); i++)
    {
    if(args[i] == "-c")
      {
      this->Synchronizer->SetResourceType(midasResourceType::COLLECTION);
      }
    else if(args[i] == "-C")
      {
      this->Synchronizer->SetResourceType(midasResourceType::COMMUNITY);
      }
    else if(args[i] == "-i")
      {
      this->Synchronizer->SetResourceType(midasResourceType::ITEM);
      }
    else if(args[i] == "-b")
      {
      this->Synchronizer->SetResourceType(midasResourceType::BITSTREAM);
      }
    else
      {
      break;
      }
    }

  if(args.size() &&
     this->Synchronizer->GetResourceType() != midasResourceType::NONE)
    {
    this->Synchronizer->SetResourceHandle(args[i]);
    return true;
    }
  else
    {
    this->PrintCommandHelp("add");
    return false;
    }
}

//-------------------------------------------------------------------
bool midasCLI::ParseClean(std::vector<std::string> args)
{
  this->Synchronizer->SetOperation(midasSynchronizer::OPERATION_CLEAN);
  return true;
}

//-------------------------------------------------------------------
bool midasCLI::ParseClone(std::vector<std::string> args)
{
  this->Synchronizer->SetOperation(midasSynchronizer::OPERATION_CLONE);
  this->Synchronizer->SetRecursive(true);

  if(args.size())
    {
    this->Synchronizer->SetServerURL(args[0]);
    return true;
    }
  else
    {
    this->PrintCommandHelp("clone");
    return false;
    }
}

//-------------------------------------------------------------------
bool midasCLI::ParsePull(std::vector<std::string> args)
{
  this->Synchronizer->SetOperation(midasSynchronizer::OPERATION_PULL);

  unsigned i;
  for(i = 0; i < args.size(); i++)
    {
    if(args[i] == "-r")
      {
      this->Synchronizer->SetRecursive(true);
      }
    else if(args[i] == "-c")
      {
      this->Synchronizer->SetResourceType(midasResourceType::COLLECTION);
      }
    else if(args[i] == "-C")
      {
      this->Synchronizer->SetResourceType(midasResourceType::COMMUNITY);
      }
    else if(args[i] == "-i")
      {
      this->Synchronizer->SetResourceType(midasResourceType::ITEM);
      }
    else if(args[i] == "-b")
      {
      this->Synchronizer->SetResourceType(midasResourceType::BITSTREAM);
      }
    else
      {
      break;
      }
    }

  if(i + 1 < args.size() &&
    this->Synchronizer->GetResourceType() != midasResourceType::NONE)
    {
    this->Synchronizer->SetServerURL(args[i]);
    i++;
    this->Synchronizer->SetResourceHandle(args[i]);
    return true;
    }
  else
    {
    this->PrintCommandHelp("pull");
    return false;
    }
}

//-------------------------------------------------------------------
bool midasCLI::ParsePush(std::vector<std::string> args)
{
  this->Synchronizer->SetOperation(midasSynchronizer::OPERATION_PUSH);
  if(!args.size())
    {
    this->PrintCommandHelp("push");
    return false;
    }
  else
    {
    this->Synchronizer->SetServerURL(args[0]);
    return true;
    }
}

//-------------------------------------------------------------------
void midasCLI::PrintUsage()
{
  std::cout << "MIDAS Command Line Interface" << std::endl
    << "Usage: MIDAScli [--database DATABASE_LOCATION] [--profile PROFILE]"
    " COMMAND [ARGS]" << std::endl << std::endl
    << "Where COMMAND is one of the following:"
    << std::endl <<
    " add              Add a file into the local repository."
    << std::endl <<
    " clean            Clean the local repository."
    << std::endl <<
    " clone            Copy an entire MIDAS database locally."
    << std::endl <<
    " create_profile   Create an authentication profile."
    << std::endl <<
    " pull             Copy part of a MIDAS database locally."
    << std::endl <<
    " push       Copy local resources to a MIDAS server."
    << std::endl << std::endl << "Use MIDAScli --help COMMAND for "
    "help with individual commands." << std::endl;
}

//-------------------------------------------------------------------
void midasCLI::PrintCommandHelp(std::string command)
{
  if(command == "pull")
    {
    std::cout << "Usage: MIDAScli ... pull [COMMAND_OPTIONS] URL "
      "RESOURCE_ID" << std::endl << "Where COMMAND_OPTIONS can be: "
      << std::endl << " -r         Copy recursively."
      << std::endl << " -C         For pulling a community."
      << std::endl << " -c         For pulling a collection."
      << std::endl << " -i         For pulling an item."
      << std::endl << " -b         For pulling a bitstream."
      << std::endl << "Exactly one type must be specified (-b, -i, -c, -C)."
      << std::endl;
    }
  else if(command == "push")
    {
    std::cout << "Usage: MIDAScli ... push -p PROFILE URL " << std::endl
      << "Where PROFILE is the name of a profile added using create_profile, "
      " and URL is the URL of the MIDAS server." << std::endl;

    }
  else if(command == "clone")
    {
    std::cout << "Usage: MIDAScli ... clone URL" << std::endl;
    }
  else if(command == "clean")
    {
    std::cout << "Usage: MIDAScli ... clean" << std::endl;
    }
  else if(command == "add")
    {
    std::cout << "Usage: MIDAScli ... add [COMMAND_OPTIONS] PATH "
      << std::endl << "Where COMMAND_OPTIONS can be: "
      << std::endl << " -C         For adding a community."
      << std::endl << " -c         For adding a collection."
      << std::endl << " -i         For adding an item."
      << std::endl << " -b         For adding a bitstream."
      << std::endl << "Exactly one type must be specified (-b, -i, -c, -C)."
      << std::endl
      << "And PATH is a relative or absolute path to the dir/file to add."
      << std::endl;
    }
  else if(command == "create_profile")
    {
      std::cout << "Usage: MIDAScli ... create_profile [PROPERTIES] URL"
      << std::endl << "Where PROPERTIES must contain all of: "
      << std::endl <<
      " --name NAME          The name of the profile to create"
      << std::endl <<
      " --email EMAIL        The user's email for logging in"
      << std::endl <<
      " --api-key KEY        The API key generated by MIDAS"
      << std::endl <<
      " --app-name APPNAME   The application name for the given key"
      << std::endl;
    }
}
<commit_msg>ENH: Fix CLI documentation a bit.<commit_after>/*=========================================================================

  Copyright (c) Kitware Inc. All rights reserved.
  See Copyright.txt or http://www.Kitware.com/Copyright.htm for details.

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

=========================================================================*/

#include "midasCLI.h"
#include "midasDotProgressReporter.h"

midasCLI::midasCLI()
{
  this->Synchronizer = new midasSynchronizer();
  this->Synchronizer->SetDatabase(
    kwsys::SystemTools::GetCurrentWorkingDirectory() + "/midas.db");
  this->Synchronizer->SetProgressReporter(
    reinterpret_cast<midasProgressReporter*>(
    new midasDotProgressReporter(30)));
}

midasCLI::~midasCLI()
{
  this->Synchronizer->DeleteProgressReporter();
  delete this->Synchronizer;
}

//-------------------------------------------------------------------
int midasCLI::Perform(std::vector<std::string> args)
{
  if(args.size() == 0)
    {
    this->PrintUsage();
    return -1;
    }

  bool ok = false;

  for(unsigned i = 0; i < args.size(); i++)
    {
    if(args[i] == "add")
      {
      std::vector<std::string> postOpArgs(args.begin() + i + 1, args.end());
      ok = this->ParseAdd(postOpArgs);
      break;
      }
    else if(args[i] == "clean")
      {
      std::vector<std::string> postOpArgs(args.begin() + i + 1, args.end());
      ok = this->ParseClean(postOpArgs);
      break;
      }
    else if(args[i] == "clone")
      {
      std::vector<std::string> postOpArgs(args.begin() + i + 1, args.end());
      ok = this->ParseClone(postOpArgs);
      break;
      }
    else if(args[i] == "create_profile")
      {
      std::vector<std::string> postOpArgs(args.begin() + i + 1, args.end());
      return this->PerformCreateProfile(postOpArgs);
      }
    else if(args[i] == "push")
      {
      std::vector<std::string> postOpArgs(args.begin() + i + 1, args.end());
      ok = this->ParsePush(postOpArgs);
      break;
      }
    else if(args[i] == "pull")
      {
      std::vector<std::string> postOpArgs(args.begin() + i + 1, args.end());
      ok = this->ParsePull(postOpArgs);
      break;
      }
    else if(args[i] == "--database" && i + 1 < args.size())
      {
      i++;
      this->Synchronizer->SetDatabase(args[i]);
      }
    else if(args[i] == "--profile" && i + 1 < args.size())
      {
      i++;
      this->Synchronizer->GetAuthenticator()->SetProfile(args[i]);
      }
    else if(args[i] == "--help")
      {
      if(i + 1 < args.size())
        {
        i++;
        this->PrintCommandHelp(args[i]);
        }
      else
        {
        this->PrintUsage();
        }
      return 0;
      }
    else
      {
      this->PrintUsage();
      return -1;
      }
    }
  return ok ? this->Synchronizer->Perform() : -1;
}

//-------------------------------------------------------------------
int midasCLI::PerformCreateProfile(std::vector<std::string> args)
{
  unsigned i;

  std::string name, user, apiKey, appName;
  for(i = 0; i < args.size(); i++)
    {
    if(args[i] == "-u" || args[i] == "--email"
      && args.size() > i + 1)
      {
      i++;
      user = args[i];
      }
    else if(args[i] == "-n" || args[i] == "--name"
      && args.size() > i + 1)
      {
      i++;
      name = args[i];
      }
    else if(args[i] == "-k" || args[i] == "--api-key"
      && args.size() > i + 1)
      {
      i++;
      apiKey = args[i];
      }
    else if(args[i] == "-a" || args[i] == "--app-name"
      && args.size() > i + 1)
      {
      i++;
      appName = args[i];
      }
    else
      {
      this->Synchronizer->SetServerURL(args[i]);
      }
    }

  if(name == "" || user == "" || apiKey == "" || appName == "")
    {
    this->PrintCommandHelp("create_profile");
    return -1;
    }

  this->

  std::cout << "Adding authentication profile '" << name << "'" << std::endl;
  bool ok = this->Synchronizer->GetAuthenticator()->AddAuthProfile(
    user, appName, apiKey, name);

  if(ok)
    {
    std::cout << "Profile successfully created." << std::endl;
    return 0;
    }
  else
    {
    std::cout << "Failed to add authentication profile." << std::endl;
    return -1;
    }
}

//-------------------------------------------------------------------
bool midasCLI::ParseAdd(std::vector<std::string> args)
{
  this->Synchronizer->SetOperation(midasSynchronizer::OPERATION_ADD);

  unsigned i;
  for(i = 0; i < args.size(); i++)
    {
    if(args[i] == "-c")
      {
      this->Synchronizer->SetResourceType(midasResourceType::COLLECTION);
      }
    else if(args[i] == "-C")
      {
      this->Synchronizer->SetResourceType(midasResourceType::COMMUNITY);
      }
    else if(args[i] == "-i")
      {
      this->Synchronizer->SetResourceType(midasResourceType::ITEM);
      }
    else if(args[i] == "-b")
      {
      this->Synchronizer->SetResourceType(midasResourceType::BITSTREAM);
      }
    else
      {
      break;
      }
    }

  if(args.size() &&
     this->Synchronizer->GetResourceType() != midasResourceType::NONE)
    {
    this->Synchronizer->SetResourceHandle(args[i]);
    return true;
    }
  else
    {
    this->PrintCommandHelp("add");
    return false;
    }
}

//-------------------------------------------------------------------
bool midasCLI::ParseClean(std::vector<std::string> args)
{
  this->Synchronizer->SetOperation(midasSynchronizer::OPERATION_CLEAN);
  return true;
}

//-------------------------------------------------------------------
bool midasCLI::ParseClone(std::vector<std::string> args)
{
  this->Synchronizer->SetOperation(midasSynchronizer::OPERATION_CLONE);
  this->Synchronizer->SetRecursive(true);

  if(args.size())
    {
    this->Synchronizer->SetServerURL(args[0]);
    return true;
    }
  else
    {
    this->PrintCommandHelp("clone");
    return false;
    }
}

//-------------------------------------------------------------------
bool midasCLI::ParsePull(std::vector<std::string> args)
{
  this->Synchronizer->SetOperation(midasSynchronizer::OPERATION_PULL);

  unsigned i;
  for(i = 0; i < args.size(); i++)
    {
    if(args[i] == "-r")
      {
      this->Synchronizer->SetRecursive(true);
      }
    else if(args[i] == "-c")
      {
      this->Synchronizer->SetResourceType(midasResourceType::COLLECTION);
      }
    else if(args[i] == "-C")
      {
      this->Synchronizer->SetResourceType(midasResourceType::COMMUNITY);
      }
    else if(args[i] == "-i")
      {
      this->Synchronizer->SetResourceType(midasResourceType::ITEM);
      }
    else if(args[i] == "-b")
      {
      this->Synchronizer->SetResourceType(midasResourceType::BITSTREAM);
      }
    else
      {
      break;
      }
    }

  if(i + 1 < args.size() &&
    this->Synchronizer->GetResourceType() != midasResourceType::NONE)
    {
    this->Synchronizer->SetServerURL(args[i]);
    i++;
    this->Synchronizer->SetResourceHandle(args[i]);
    return true;
    }
  else
    {
    this->PrintCommandHelp("pull");
    return false;
    }
}

//-------------------------------------------------------------------
bool midasCLI::ParsePush(std::vector<std::string> args)
{
  this->Synchronizer->SetOperation(midasSynchronizer::OPERATION_PUSH);
  if(!args.size())
    {
    this->PrintCommandHelp("push");
    return false;
    }
  else
    {
    this->Synchronizer->SetServerURL(args[0]);
    return true;
    }
}

//-------------------------------------------------------------------
void midasCLI::PrintUsage()
{
  std::cout << "MIDAS Command Line Interface" << std::endl
    << "Usage: MIDAScli [--database DATABASE_LOCATION] [--profile PROFILE]"
    " COMMAND [ARGS]" << std::endl << std::endl
    << "Where COMMAND is one of the following:"
    << std::endl <<
    " add              Add a file into the local repository."
    << std::endl <<
    " clean            Clean the local repository."
    << std::endl <<
    " clone            Copy an entire MIDAS database locally."
    << std::endl <<
    " create_profile   Create an authentication profile."
    << std::endl <<
    " pull             Copy part of a MIDAS database locally."
    << std::endl <<
    " push             Copy local resources to a MIDAS server."
    << std::endl << std::endl << "Use MIDAScli --help COMMAND for "
    "help with individual commands." << std::endl;
}

//-------------------------------------------------------------------
void midasCLI::PrintCommandHelp(std::string command)
{
  if(command == "pull")
    {
    std::cout << "Usage: MIDAScli ... pull [COMMAND_OPTIONS] URL "
      "RESOURCE_ID" << std::endl << "Where COMMAND_OPTIONS can be: "
      << std::endl << " -r         Copy recursively."
      << std::endl << " -C         For pulling a community."
      << std::endl << " -c         For pulling a collection."
      << std::endl << " -i         For pulling an item."
      << std::endl << " -b         For pulling a bitstream."
      << std::endl << "Exactly one type must be specified (-b, -i, -c, -C)."
      << std::endl;
    }
  else if(command == "push")
    {
    std::cout << "Usage: MIDAScli ... push -p PROFILE URL " << std::endl
      << "Where PROFILE is the name of a profile added using create_profile, "
      " and URL is the URL of the MIDAS server." << std::endl;

    }
  else if(command == "clone")
    {
    std::cout << "Usage: MIDAScli ... clone URL" << std::endl;
    }
  else if(command == "clean")
    {
    std::cout << "Usage: MIDAScli ... clean" << std::endl;
    }
  else if(command == "add")
    {
    std::cout << "Usage: MIDAScli ... add [COMMAND_OPTIONS] PATH "
      << std::endl << "Where COMMAND_OPTIONS can be: "
      << std::endl << " -C         For adding a community."
      << std::endl << " -c         For adding a collection."
      << std::endl << " -i         For adding an item."
      << std::endl << " -b         For adding a bitstream."
      << std::endl << "Exactly one type must be specified (-b, -i, -c, -C)."
      << std::endl
      << "And PATH is a relative or absolute path to the dir/file to add."
      << std::endl;
    }
  else if(command == "create_profile")
    {
      std::cout << "Usage: MIDAScli ... create_profile [PROPERTIES] URL"
      << std::endl << "Where PROPERTIES must contain all of: "
      << std::endl <<
      " --name NAME          The name of the profile to create"
      << std::endl <<
      " --email EMAIL        The user's email for logging in"
      << std::endl <<
      " --api-key KEY        The API key generated by MIDAS"
      << std::endl <<
      " --app-name APPNAME   The application name for the given key"
      << std::endl;
    }
}
<|endoftext|>


<commit_before>/*
 * Medical Image Registration ToolKit (MIRTK)
 *
 * Copyright 2013-2015 Imperial College London
 * Copyright 2013-2015 Andreas Schuh
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <mirtkCommon.h>
#include <mirtkOptions.h>

#include <mirtkPointSetUtils.h>

#include <vtkMath.h>
#include <vtkPointSet.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include <vtkFloatArray.h>
#include <vtkCellLocator.h>
#include <vtkPolyDataNormals.h>
#include <vtkKdTreePointLocator.h>

using namespace mirtk;

// =============================================================================
// Help
// =============================================================================

// -----------------------------------------------------------------------------
void PrintHelp(const char *name)
{
  cout << endl;
  cout << "Usage: " << name << " <target> <source> [<output>] [options]" << endl;
  cout << endl;
  cout << "Description:" << endl;
  cout << "  Evaluate distance between two given point sets." << endl;
  cout << endl;
  cout << "Optional arguments:" << endl;
  cout << "  -name   Name of output point distance array. (default: Distance)" << endl;
  PrintStandardOptions(cout);
  cout << endl;
}

// =============================================================================
// Auxiliaries
// =============================================================================

// -----------------------------------------------------------------------------
/// Evaluate distance of target to closest source points
void EvaluateClosestPointDistance(vtkPointSet *target, vtkPointSet *source, vtkDataArray *distance)
{
  vtkIdType otherPtId;
  double    a[3], b[3];

  vtkSmartPointer<vtkAbstractPointLocator> locator;
  locator = vtkSmartPointer<vtkKdTreePointLocator>::New();
  locator->SetDataSet(source);
  locator->BuildLocator();

  for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
    target->GetPoint(ptId, a);
    otherPtId = locator->FindClosestPoint(a);
    source->GetPoint(otherPtId, b);
    distance->SetComponent(ptId, 0, sqrt(vtkMath::Distance2BetweenPoints(a, b)));
  }
}

// -----------------------------------------------------------------------------
/// Evaluate distance of target to closest source cell point
void EvaluateClosestCellDistance(vtkPointSet *target, vtkPointSet *source, vtkDataArray *distance)
{
  int       subId;
  vtkIdType cellId;
  double    a[3], b[3], dist;

  vtkSmartPointer<vtkAbstractCellLocator> locator;
  locator = vtkSmartPointer<vtkCellLocator>::New();
  locator->SetDataSet(source);
  locator->BuildLocator();

  for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
    target->GetPoint(ptId, a);
    locator->FindClosestPoint(a, b, cellId, subId, dist);
    distance->SetComponent(ptId, 0, sqrt(dist));
  }
}

// -----------------------------------------------------------------------------
/// Evaluate distance of corresponding points
void EvaluateCorrespondingPointDistance(vtkPointSet *target, vtkPointSet *source, vtkDataArray *distance)
{
  if (target->GetNumberOfPoints() != source->GetNumberOfPoints()) {
    FatalError("Point sets must have equal number of points to evaluate -corr point distance");
  }

  double a[3], b[3];

  for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
    target->GetPoint(ptId, a);
    source->GetPoint(ptId, b);
    distance->SetComponent(ptId, 0, sqrt(vtkMath::Distance2BetweenPoints(a, b)));
  }
}

// -----------------------------------------------------------------------------
/// Evaluate distance of target to closest source cell point in normal direction
void EvaluateNormalDistance(vtkPointSet *target, vtkPointSet *source, vtkDataArray *distance,
                            double default_value = numeric_limits<double>::quiet_NaN())
{
  vtkPolyData *surface = vtkPolyData::SafeDownCast(target);
  if (surface == NULL) {
    FatalError("Cannot compute distance along -normal for non-polygonal point set");
  }

  vtkNew<vtkPolyDataNormals> calc_normals;
  calc_normals->ComputeCellNormalsOff();
  calc_normals->ComputePointNormalsOn();
  calc_normals->AutoOrientNormalsOn();
  calc_normals->SplittingOff();
  SetVTKInput(calc_normals, surface);
  calc_normals->Update();

  vtkSmartPointer<vtkDataArray> normals;
  normals = calc_normals->GetOutput()->GetPointData()->GetNormals();

  int    subId;
  double a[3], b[3], n[3], x[3], t, pcoords[3], dist;

  const double max_dist = 1000.0;

  vtkSmartPointer<vtkAbstractCellLocator> locator;
  locator = vtkSmartPointer<vtkCellLocator>::New();
  locator->SetDataSet(source);
  locator->BuildLocator();

  for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
    dist = numeric_limits<double>::infinity();
    target->GetPoint(ptId, a);
    normals->GetTuple(ptId, n);
    b[0] = a[0] + max_dist * n[0];
    b[1] = a[1] + max_dist * n[1];
    b[2] = a[2] + max_dist * n[2];
    if (locator->IntersectWithLine(a, b, .0, t, x, pcoords, subId)) {
      dist = sqrt(vtkMath::Distance2BetweenPoints(a, x));
    }
    b[0] = a[0] - max_dist * n[0];
    b[1] = a[1] - max_dist * n[1];
    b[2] = a[2] - max_dist * n[2];
    if (locator->IntersectWithLine(a, b, .0, t, x, pcoords, subId)) {
      dist = min(dist, sqrt(vtkMath::Distance2BetweenPoints(a, x)));
    }
    if (IsInf(dist)) dist = default_value;
    distance->SetComponent(ptId, 0, dist);
  }
}

// =============================================================================
// Main
// =============================================================================

// -----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
  // Parse arguments
  REQUIRES_POSARGS(2);

  const char *target_name = POSARG(1);
  const char *source_name = POSARG(2);
  const char *output_name = NULL;

  if (NUM_POSARGS == 3) {
    output_name = POSARG(3);
  } else if (NUM_POSARGS > 3) {
    PrintHelp(EXECNAME);
    exit(1);
  }

  enum DistanceType
  {
    ClosestPoint,
    ClosestCell,
    AlongNormal,
    CorrespondingPoint
  };

  const char  *array_name     = "Distance";
  DistanceType dist_type      = ClosestPoint;
  bool         eval_hausdorff = false;

  for (ALL_OPTIONS) {
    if      (OPTION("-name"))      array_name     = ARGUMENT;
    else if (OPTION("-point"))     dist_type      = ClosestPoint;
    else if (OPTION("-cell"))      dist_type      = ClosestCell;
    else if (OPTION("-normal"))    dist_type      = AlongNormal;
    else if (OPTION("-corr"))      dist_type      = CorrespondingPoint;
    else if (OPTION("-hausdorff")) eval_hausdorff = true;
    else HANDLE_COMMON_OR_UNKNOWN_OPTION();
  }

  // read input point sets
  vtkSmartPointer<vtkPointSet> target, source;
  target = ReadPointSet(target_name);
  source = ReadPointSet(source_name);

  if (dist_type == ClosestCell) {
    if (source->GetNumberOfCells() == 0) {
      FatalError("Cannot evaluation -cell distance when source has no cells");
    }
    if (eval_hausdorff && target->GetNumberOfCells() == 0) {
      FatalError("Cannot evaluation -cell -hausdorff distance when target has no cells");
    }
  }

  if (eval_hausdorff && dist_type != ClosestPoint && dist_type != ClosestCell) {
    FatalError("Hausdorff distance currenly only implemented for -point or -cell distance");
  }

  // find closest source points
  int       subId;
  vtkIdType otherPtId, cellId;
  double    a[3], b[3], dist;

  vtkSmartPointer<vtkFloatArray> distance;
  distance = vtkSmartPointer<vtkFloatArray>::New();
  distance->SetName(array_name);
  distance->SetNumberOfComponents(1);
  distance->SetNumberOfTuples(target->GetNumberOfPoints());
  target->GetPointData()->AddArray(distance);

  switch (dist_type) {
    case ClosestPoint:       EvaluateClosestPointDistance      (target, source, distance); break;
    case ClosestCell:        EvaluateClosestCellDistance       (target, source, distance); break;
    case AlongNormal:        EvaluateNormalDistance            (target, source, distance); break;
    case CorrespondingPoint: EvaluateCorrespondingPointDistance(target, source, distance); break;
  }

  // calculate min/max and average distance
  double sum_dist = .0;
  double min_dist = +numeric_limits<double>::infinity();
  double max_dist = -numeric_limits<double>::infinity();

  for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
    dist = distance->GetComponent(ptId, 0);
    sum_dist += dist;
    if (dist < min_dist) min_dist = dist;
    if (dist > max_dist) max_dist = dist;
  }

  // calculate Hausdorff distance
  double hausdorff_dist = max_dist;
  if (eval_hausdorff) {
    if (dist_type == ClosestCell) {

      vtkSmartPointer<vtkAbstractCellLocator> locator;
      locator = vtkSmartPointer<vtkCellLocator>::New();
      locator->SetDataSet(target);
      locator->BuildLocator();

      for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
        source->GetPoint(ptId, a);
        locator->FindClosestPoint(a, b, cellId, subId, dist);
        dist = sqrt(dist);
        if (dist > hausdorff_dist) hausdorff_dist = dist;
      }

    } else {

      vtkSmartPointer<vtkAbstractPointLocator> locator;
      locator = vtkSmartPointer<vtkKdTreePointLocator>::New();
      locator->SetDataSet(target);
      locator->BuildLocator();

      for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
        source->GetPoint(ptId, a);
        otherPtId = locator->FindClosestPoint(a);
        source->GetPoint(otherPtId, b);
        dist = sqrt(vtkMath::Distance2BetweenPoints(a, b));
        if (dist > hausdorff_dist) hausdorff_dist = dist;
      }

    }
  }

  // write output
  if (output_name) {
    if (!WritePointSet(output_name, target)) {
      FatalError("Failed to write output point set to " << output_name);
    }
  }

  // print distances and summary
  if (verbose) {
    cout << "ID,PointDistance" << endl;
    for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
      cout << (ptId+1) << "," << distance->GetComponent(ptId, 0) << endl;
    }
    cout << endl;
  }
  cout << "Minimum distance = " << min_dist << endl;
  cout << "Maximum distance = " << max_dist << endl;
  cout << "Average distance = " << sum_dist / target->GetNumberOfPoints() << endl;
  if (eval_hausdorff) cout << "Hausdorff distance: " << hausdorff_dist << endl;

  return 0;
}
<commit_msg>enh: Document and add additional options to evaluate-distance [Applications]<commit_after>/*
 * Medical Image Registration ToolKit (MIRTK)
 *
 * Copyright 2013-2015 Imperial College London
 * Copyright 2013-2015 Andreas Schuh
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <mirtkCommon.h>
#include <mirtkOptions.h>

#include <mirtkPointSetUtils.h>

#include <vtkMath.h>
#include <vtkPointSet.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include <vtkFloatArray.h>
#include <vtkCellLocator.h>
#include <vtkPolyDataNormals.h>
#include <vtkModifiedBSPTree.h>
#include <vtkKdTreePointLocator.h>
#include <vtkDataReader.h> // VTK_ASCII, VTK_BINARY defines

using namespace mirtk;

// =============================================================================
// Help
// =============================================================================

// -----------------------------------------------------------------------------
void PrintHelp(const char *name)
{
  cout << endl;
  cout << "Usage: " << name << " <target> <source> [<output>] [options]" << endl;
  cout << endl;
  cout << "Description:" << endl;
  cout << "  Evaluate distance between two given point sets. With increased verbosity (see :option:`-v`)," << endl;
  cout << "  the mean and standard deviation of the measured distances  (verbosity level >=1) and the" << endl;
  cout << "  individual distance for each target point is reported (verbosity level >=2)." << endl;
  cout << endl;
  cout << "Arguments:" << endl;
  cout << "  target   Target point set/surface." << endl;
  cout << "  source   Source point set/surface." << endl;
  cout << "  output   Output point set/surface with point data array of measured distances. (default: none)" << endl;
  cout << endl;
  cout << "Optional arguments:" << endl;
  cout << "  -name <name>       Name of output point data array or column header. (default: Distance)" << endl;
  cout << "  -separator <sep>   Column separator used for table of measured point distances. (default: \\t)" << endl;
  cout << "  -point             Evaluate minimum distance to closest point. (default for point clouds)" << endl;
  cout << "  -cell              Evaluate minimum distance to closest surface point. (default for surface meshes)" << endl;
  cout << "  -normal            Evaluate minimum distance along surface normal." << endl;
  cout << "  -index             Evaluate distance between points with identical index, e.g., pairs of fiducial markers." << endl;
  cout << "  -hausdorff         Report Hausdorff distance. (default: off)" << endl;
  PrintStandardOptions(cout);
  cout << endl;
}

// =============================================================================
// Auxiliaries
// =============================================================================

// -----------------------------------------------------------------------------
/// Evaluate distance of target to closest source points
void EvaluateClosestPointDistance(vtkPointSet *target, vtkPointSet *source, vtkDataArray *distance)
{
  vtkIdType otherPtId;
  double    a[3], b[3];

  vtkNew<vtkKdTreePointLocator> locator;
  locator->SetDataSet(source);
  locator->BuildLocator();

  for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
    target->GetPoint(ptId, a);
    otherPtId = locator->FindClosestPoint(a);
    source->GetPoint(otherPtId, b);
    distance->SetComponent(ptId, 0, sqrt(vtkMath::Distance2BetweenPoints(a, b)));
  }
}

// -----------------------------------------------------------------------------
/// Evaluate distance of target to closest source cell point
void EvaluateClosestCellDistance(vtkPointSet *target, vtkPointSet *source, vtkDataArray *distance)
{
  int       subId;
  vtkIdType cellId;
  double    a[3], b[3], dist2;

  vtkNew<vtkCellLocator> locator;
  locator->SetDataSet(source);
  locator->BuildLocator();

  for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
    target->GetPoint(ptId, a);
    locator->FindClosestPoint(a, b, cellId, subId, dist2);
    distance->SetComponent(ptId, 0, sqrt(dist2));
  }
}

// -----------------------------------------------------------------------------
/// Evaluate distance of corresponding points
void EvaluateCorrespondingPointDistance(vtkPointSet *target, vtkPointSet *source, vtkDataArray *distance)
{
  if (target->GetNumberOfPoints() != source->GetNumberOfPoints()) {
    FatalError("Point sets must have equal number of points to evaluate -corr point distance");
  }

  double a[3], b[3];

  for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
    target->GetPoint(ptId, a);
    source->GetPoint(ptId, b);
    distance->SetComponent(ptId, 0, sqrt(vtkMath::Distance2BetweenPoints(a, b)));
  }
}

// -----------------------------------------------------------------------------
/// Evaluate distance of target to closest source cell point in normal direction
void EvaluateNormalDistance(vtkPointSet *target, vtkPointSet *source, vtkDataArray *distance,
                            double default_value = numeric_limits<double>::quiet_NaN())
{
  vtkPolyData *surface = vtkPolyData::SafeDownCast(target);
  if (surface == NULL) {
    FatalError("Cannot compute distance along -normal for non-polygonal point set");
  }

  vtkNew<vtkPolyDataNormals> calc_normals;
  calc_normals->ComputeCellNormalsOff();
  calc_normals->ComputePointNormalsOn();
  calc_normals->AutoOrientNormalsOn();
  calc_normals->SplittingOff();
  SetVTKInput(calc_normals, surface);
  calc_normals->Update();

  vtkSmartPointer<vtkDataArray> normals;
  normals = calc_normals->GetOutput()->GetPointData()->GetNormals();

  int    subId;
  double a[3], b[3], n[3], x[3], t, pcoords[3], dist;

  const double max_dist = 1000.0;

  vtkNew<vtkModifiedBSPTree> locator;
  locator->SetDataSet(source);
  locator->BuildLocator();

  for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
    dist = numeric_limits<double>::infinity();
    target->GetPoint(ptId, a);
    normals->GetTuple(ptId, n);
    b[0] = a[0] + max_dist * n[0];
    b[1] = a[1] + max_dist * n[1];
    b[2] = a[2] + max_dist * n[2];
    if (locator->IntersectWithLine(a, b, .0, t, x, pcoords, subId)) {
      dist = sqrt(vtkMath::Distance2BetweenPoints(a, x));
    }
    b[0] = a[0] - max_dist * n[0];
    b[1] = a[1] - max_dist * n[1];
    b[2] = a[2] - max_dist * n[2];
    if (locator->IntersectWithLine(a, b, .0, t, x, pcoords, subId)) {
      dist = min(dist, sqrt(vtkMath::Distance2BetweenPoints(a, x)));
    }
    if (IsInf(dist)) dist = default_value;
    distance->SetComponent(ptId, 0, dist);
  }
}

// =============================================================================
// Main
// =============================================================================

// -----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
  // Parse arguments
  REQUIRES_POSARGS(2);

  const char *target_name = POSARG(1);
  const char *source_name = POSARG(2);
  const char *output_name = nullptr;

  if (NUM_POSARGS == 3) {
    output_name = POSARG(3);
  } else if (NUM_POSARGS > 3) {
    PrintHelp(EXECNAME);
    exit(1);
  }

  enum DistanceType
  {
    Default,
    ClosestPoint,
    ClosestCell,
    AlongNormal,
    CorrespondingPoint
  };

  const char  *array_name     = "Distance";
  const char  *separator      = "\t";
  DistanceType dist_type      = Default;
  bool         eval_hausdorff = false;

  for (ALL_OPTIONS) {
    if      (OPTION("-array") || OPTION("-name")) array_name = ARGUMENT;
    else if (OPTION("-point"))     dist_type      = ClosestPoint;
    else if (OPTION("-cell"))      dist_type      = ClosestCell;
    else if (OPTION("-normal"))    dist_type      = AlongNormal;
    else if (OPTION("-index"))     dist_type      = CorrespondingPoint;
    else if (OPTION("-hausdorff")) eval_hausdorff = true;
    else if (OPTION("-sep") || OPTION("-separator") || OPTION("-delimiter")) {
      separator = ARGUMENT;
      if (strcmp(separator, "\\t") == 0) separator = "\t";
    }
    else HANDLE_COMMON_OR_UNKNOWN_OPTION();
  }

  // read input point sets
  int output_type = VTK_BINARY;
  vtkSmartPointer<vtkPointSet> target, source;
  target = ReadPointSet(target_name);
  source = ReadPointSet(source_name, &output_type);

  if (dist_type == Default) {
    if (target->GetNumberOfCells() > 0) dist_type = ClosestCell;
    else                                dist_type = ClosestPoint;
  }
  if (dist_type == ClosestCell) {
    if (source->GetNumberOfCells() == 0) {
      FatalError("Cannot evaluation -cell distance when source has no cells");
    }
    if (eval_hausdorff && target->GetNumberOfCells() == 0) {
      FatalError("Cannot evaluation -cell -hausdorff distance when target has no cells");
    }
  }

  if (eval_hausdorff && dist_type != ClosestPoint && dist_type != ClosestCell) {
    FatalError("Hausdorff distance currenly only implemented for -point or -cell distance");
  }

  // find closest source points
  int       subId;
  vtkIdType otherPtId, cellId;
  double    a[3], b[3], dist;

  vtkSmartPointer<vtkFloatArray> distance;
  distance = vtkSmartPointer<vtkFloatArray>::New();
  distance->SetName(array_name);
  distance->SetNumberOfComponents(1);
  distance->SetNumberOfTuples(target->GetNumberOfPoints());
  target->GetPointData()->AddArray(distance);

  switch (dist_type) {
    case Default: // never the case
    case ClosestPoint:       EvaluateClosestPointDistance      (target, source, distance); break;
    case ClosestCell:        EvaluateClosestCellDistance       (target, source, distance); break;
    case AlongNormal:        EvaluateNormalDistance            (target, source, distance); break;
    case CorrespondingPoint: EvaluateCorrespondingPointDistance(target, source, distance); break;
  }

  // calculate min/max and average distance
  double sum_dist = .0;
  double min_dist = +numeric_limits<double>::infinity();
  double max_dist = -numeric_limits<double>::infinity();

  for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
    dist = distance->GetComponent(ptId, 0);
    sum_dist += dist;
    if (dist < min_dist) min_dist = dist;
    if (dist > max_dist) max_dist = dist;
  }

  // calculate Hausdorff distance
  double hausdorff_dist = max_dist;
  if (eval_hausdorff) {
    if (dist_type == ClosestCell) {

      vtkNew<vtkCellLocator> locator;
      locator->SetDataSet(target);
      locator->BuildLocator();

      for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
        source->GetPoint(ptId, a);
        locator->FindClosestPoint(a, b, cellId, subId, dist);
        dist = sqrt(dist);
        if (dist > hausdorff_dist) hausdorff_dist = dist;
      }

    } else {

      vtkNew<vtkKdTreePointLocator> locator;
      locator->SetDataSet(target);
      locator->BuildLocator();

      for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
        source->GetPoint(ptId, a);
        otherPtId = locator->FindClosestPoint(a);
        source->GetPoint(otherPtId, b);
        dist = sqrt(vtkMath::Distance2BetweenPoints(a, b));
        if (dist > hausdorff_dist) hausdorff_dist = dist;
      }

    }
  }

  // write output
  if (output_name) {
    const bool compress = true;
    if (!WritePointSet(output_name, target, compress, output_type == VTK_ASCII)) {
      FatalError("Failed to write output point set to " << output_name);
    }
  }

  // print distances and summary
  if (verbose > 1) {
    cout << "ID" << separator << array_name << "\n";
    for (vtkIdType ptId = 0; ptId < target->GetNumberOfPoints(); ++ptId) {
      cout << (ptId+1) << separator << distance->GetComponent(ptId, 0) << "\n";
    }
    cout << "\n";
  }
  if (verbose || !output_name) {
    cout << "Minimum distance   = " << min_dist << "\n";
    cout << "Maximum distance   = " << max_dist << "\n";
    cout << "Average distance   = " << sum_dist / target->GetNumberOfPoints() << "\n";
  }
  if (eval_hausdorff) cout << "Hausdorff distance = " << hausdorff_dist << "\n";

  return 0;
}
<|endoftext|>


<commit_before><commit_msg>Reading corpus data and make array of data and char set<commit_after>//This program created by love by Hadi - Copyright(c) by Hadi Abdi Khojasteh - Summer 2017. All right reserved. / Email: hkhojasteh@iasbs.ac.ir, info@hadiabdikhojasteh.ir / Website: iasbs.ac.ir/~hkhojasteh, hadiabdikhojasteh.ir

#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/ml/ml.hpp>

#include <iostream>
#include <vector>

using namespace std;
using namespace cv;
using namespace cv::ml;

int main() {
	vector<char> data;
	vector<char> chars;
	FILE* inputfile;
	string fileName = "input.txt";
	inputfile = fopen(fileName.c_str(), "r");

	while (!feof(inputfile)) {
		char inchar[1] = { 0 };
		fscanf(inputfile, "%c", inchar);
		data.push_back(inchar[0]);

		auto it = find_if(chars.begin(), chars.end(),
			[&](const char element) { return element == inchar[0]; });
		//If this is not in the char set
		if (it == end(chars)) {
			chars.push_back(inchar[0]);
		}
	}

	return 0;
}<|endoftext|>


<commit_before>#include <stdlib.h>
#ifdef WIN32
  #define _CRTDBG_MAP_ALLOC
  #include <crtdbg.h>
  #include <conio.h>
#endif

#include <cstdio>
//#include <cstdlib>

#include <iostream>

#include <SocketHandler.h>
#include <ListenSocket.h>
#include "StatusHandler.h"

#include "DisplaySocket.h"
#include "map.h"

static	bool quit = false;

StatusHandler h;
ListenSocket<DisplaySocket> l(h);

int main(void)
{
    uint32 starttime=time(0);

#ifdef WIN32
  _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
  _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
#endif

  initMap();
  atexit(freeMap);

  //Bind to port 25565
	if (l.Bind(25565))
	{
		exit(-1);
	}
	h.Add(&l);
	h.Select(1,0);
	while (!quit)
	{
		h.Select(1,0);
        if(time(0)-starttime>10)
        {
            starttime=time(0);
            std::cout << "Currently " << h.GetCount()-1 << " users in!" << std::endl;
        }
        #ifdef WIN32
        if(kbhit())
            quit=1;
        #endif
	}

  freeMap();
  l.CloseAndDelete();

  //Windows debug
  #ifdef WIN32
      _CrtDumpMemoryLeaks();
  #endif

  return EXIT_SUCCESS;
}<commit_msg>+ Added startup message<commit_after>#include <stdlib.h>
#ifdef WIN32
  #define _CRTDBG_MAP_ALLOC
  #include <crtdbg.h>
  #include <conio.h>
#endif

#include <cstdio>
//#include <cstdlib>

#include <iostream>

#include <SocketHandler.h>
#include <ListenSocket.h>
#include "StatusHandler.h"

#include "DisplaySocket.h"
#include "map.h"

static	bool quit = false;

StatusHandler h;
ListenSocket<DisplaySocket> l(h);

int main(void)
{
    uint32 starttime=time(0);

#ifdef WIN32
  _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
  _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
#endif

  initMap();
  atexit(freeMap);

  //Bind to port 25565
	if (l.Bind(25565))
	{
		exit(-1);
	}
    std::cout << std::endl
              << "    _/      _/  _/                                                                                " << std::endl
              << "   _/_/  _/_/      _/_/_/      _/_/      _/_/_/    _/_/    _/  _/_/  _/      _/    _/_/    _/  _/_/   " << std::endl
              << "  _/  _/  _/  _/  _/    _/  _/_/_/_/  _/_/      _/_/_/_/  _/_/      _/      _/  _/_/_/_/  _/_/        " << std::endl
              << " _/      _/  _/  _/    _/  _/            _/_/  _/        _/          _/  _/    _/        _/           " << std::endl
              << "_/      _/  _/  _/    _/    _/_/_/  _/_/_/      _/_/_/  _/            _/        _/_/_/  _/            " << std::endl;
    std::cout << "Version 0.1 by Fador(&Psoden -_-)" << std::endl << std:endl;
	h.Add(&l);
	h.Select(1,0);
	while (!quit)
	{
		h.Select(1,0);
        if(time(0)-starttime>10)
        {
            starttime=time(0);
            std::cout << "Currently " << h.GetCount()-1 << " users in!" << std::endl;
        }
        #ifdef WIN32
        if(kbhit())
            quit=1;
        #endif
	}

  freeMap();
  l.CloseAndDelete();

  //Windows debug
  #ifdef WIN32
      _CrtDumpMemoryLeaks();
  #endif

  return EXIT_SUCCESS;
}<|endoftext|>


<commit_before>/**
 * Copyright (c) 2007-2012, Timothy Stack
 *
 * 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 Timothy Stack 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 REGENTS 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 REGENTS 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 vt52_curses.cc
 */

#include "config.h"

#include <unistd.h>
#include <string.h>

#include <map>

#include "lnav_log.hh"
#include "vt52_curses.hh"

#if defined HAVE_NCURSESW_CURSES_H
#  include <ncursesw/curses.h>
#  include <ncursesw/term.h>
#elif defined HAVE_NCURSESW_H
#  include <ncursesw.h>
#  include <term.h>
#elif defined HAVE_NCURSES_CURSES_H
#  include <ncurses/curses.h>
#  include <ncurses/term.h>
#elif defined HAVE_NCURSES_H
#  include <ncurses.h>
#  include <term.h>
#elif defined HAVE_CURSES_H
#  include <curses.h>
#  include <term.h>
#else
#  error "SysV or X/Open-compatible Curses header file required"
#endif

using namespace std;

/**
 * Singleton used to hold the mapping of ncurses keycodes to VT52 escape
 * sequences.
 */
class vt52_escape_map {
public:

    /** @return The singleton. */
    static vt52_escape_map &singleton()
    {
        static vt52_escape_map s_vem;

        return s_vem;
    };

    /**
     * @param ch The ncurses keycode.
     * @return The null terminated VT52 escape sequence.
     */
    const char *operator[](int ch) const
    {
        map<int, const char *>::const_iterator iter;
        const char *retval = NULL;

        if ((iter = this->vem_map.find(ch)) != this->vem_map.end()) {
            retval = iter->second;
        }

        return retval;
    };

    const char *operator[](const char *seq) const
    {
        map<string, const char *>::const_iterator iter;
        const char *retval = NULL;

        require(seq != NULL);

        if ((iter = this->vem_input_map.find(seq)) !=
            this->vem_input_map.end()) {
            retval = iter->second;
        }

        return retval;
    };

private:

    /** Construct the map with a few escape sequences. */
    vt52_escape_map()
    {
        static char area_buffer[1024];
        char *      area = area_buffer;

        if (tgetent(NULL, "vt52") == ERR) {
            perror("tgetent");
        }
        this->vem_map[KEY_UP]        = tgetstr((char *)"ku", &area);
        this->vem_map[KEY_DOWN]      = tgetstr((char *)"kd", &area);
        this->vem_map[KEY_RIGHT]     = tgetstr((char *)"kr", &area);
        this->vem_map[KEY_LEFT]      = tgetstr((char *)"kl", &area);
        this->vem_map[KEY_HOME]      = tgetstr((char *)"kh", &area);
        this->vem_map[KEY_BACKSPACE] = "\010";
        this->vem_map[KEY_DC]        = "\x4";

        this->vem_map[KEY_BEG] = "\x1";
        this->vem_map[KEY_END] = "\x5";

        this->vem_map[KEY_SLEFT] = tgetstr((char *)"#4", &area);
        if (this->vem_map[KEY_SLEFT] == NULL) {
            this->vem_map[KEY_SLEFT] = "\033b";
        }
        this->vem_map[KEY_SRIGHT] = tgetstr((char *)"%i", &area);
        if (this->vem_map[KEY_SRIGHT] == NULL) {
            this->vem_map[KEY_SRIGHT] = "\033f";
        }

        this->vem_input_map[tgetstr((char *)"ce", &area)] = "ce";
        this->vem_input_map[tgetstr((char *)"kl", &area)] = "kl";
        this->vem_input_map[tgetstr((char *)"kr", &area)] = "kr";
        tgetent(NULL, getenv("TERM"));
    };

    /** Map of ncurses keycodes to VT52 escape sequences. */
    map<int, const char *>    vem_map;
    map<string, const char *> vem_input_map;
};

vt52_curses::vt52_curses()
    : vc_window(NULL),
      vc_x(0),
      vc_y(0),
      vc_max_height(0),
      vc_escape_len(0),
      vc_map_buffer(0)
{ }

vt52_curses::~vt52_curses()
{ }

const char *vt52_curses::map_input(int ch, int &len_out)
{
    const char *esc, *retval;

    /* Check for an escape sequence, otherwise just return the char. */
    if ((esc = vt52_escape_map::singleton()[ch]) != NULL) {
        retval  = esc;
        len_out = strlen(retval);
    }
    else {
        this->vc_map_buffer = (char)ch;
        retval  = &this->vc_map_buffer; /* XXX probably shouldn't do this. */
        len_out = 1;
    }

    ensure(retval != NULL);
    ensure(len_out > 0);

    return retval;
}

void vt52_curses::map_output(const char *output, int len)
{
    int y, lpc;

    require(this->vc_window != NULL);

    y = this->get_actual_y();
    wmove(this->vc_window, y, this->vc_x);
    for (lpc = 0; lpc < len; lpc++) {
        if (this->vc_escape_len > 0) {
            const char *cap;

            this->vc_escape[this->vc_escape_len] = output[lpc];
            this->vc_escape_len += 1;
            this->vc_escape[this->vc_escape_len] = '\0';

            if ((cap = vt52_escape_map::singleton()[this->vc_escape]) !=
                NULL) {
                if (strcmp(cap, "ce") == 0) {
                    wclrtoeol(this->vc_window);
                    this->vc_escape_len = 0;
                }
                else if (strcmp(cap, "kl") == 0) {
                    this->vc_x -= 1;
                    wmove(this->vc_window, y, this->vc_x);
                    this->vc_escape_len = 0;
                }
                else if (strcmp(cap, "kr") == 0) {
                    this->vc_x += 1;
                    wmove(this->vc_window, y, this->vc_x);
                    this->vc_escape_len = 0;
                }
                else {
                    ensure(0);
                }
            }
        }
        else {
            switch (output[lpc]) {
            case STX:
                this->vc_past_lines.clear();
                this->vc_x = 0;
                wmove(this->vc_window, y, this->vc_x);
                wclrtoeol(this->vc_window);
                break;

            case BELL:
                flash();
                break;

            case BACKSPACE:
                this->vc_x -= 1;
                wmove(this->vc_window, y, this->vc_x);
                break;

            case ESCAPE:
                this->vc_escape[0]  = ESCAPE;
                this->vc_escape_len = 1;
                break;

            case '\n':
            {
                unsigned long width, height;
                char *        buffer;

                getmaxyx(this->vc_window, height, width);

                buffer     = (char *)alloca(width);
                this->vc_x = 0;
                wmove(this->vc_window, y, this->vc_x);

                /*
                 * XXX Not sure why we need to subtract one from the width
                 * here, but otherwise it seems to spill over and screw up
                 * the next line when we're writing it back out in
                 * do_update().
                 */
                winnstr(this->vc_window, buffer, width - 1);
                this->vc_past_lines.push_back(buffer);
                wclrtoeol(this->vc_window);
            }
            break;

            case '\r':
                this->vc_x = 0;
                wmove(this->vc_window, y, this->vc_x);
                break;

            default:
                mvwaddch(this->vc_window, y, this->vc_x, output[lpc]);
                this->vc_x += 1;
                break;
            }
        }
    }
}

void vt52_curses::do_update(void)
{
    list<string>::iterator iter;
    int y;

    y = this->get_actual_y() - (int)this->vc_past_lines.size();
    for (iter = this->vc_past_lines.begin();
         iter != this->vc_past_lines.end();
         ++iter, y++) {
        if (y >= 0) {
            mvwprintw(this->vc_window, y, 0, "%s", iter->c_str());
            wclrtoeol(this->vc_window);
        }
    }
    wmove(this->vc_window, y, this->vc_x);
}
<commit_msg>[-Wunused-but-set-variable] vt52_curses.cc<commit_after>/**
 * Copyright (c) 2007-2012, Timothy Stack
 *
 * 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 Timothy Stack 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 REGENTS 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 REGENTS 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 vt52_curses.cc
 */

#include "config.h"

#include <unistd.h>
#include <string.h>

#include <map>

#include "lnav_log.hh"
#include "vt52_curses.hh"

#if defined HAVE_NCURSESW_CURSES_H
#  include <ncursesw/curses.h>
#  include <ncursesw/term.h>
#elif defined HAVE_NCURSESW_H
#  include <ncursesw.h>
#  include <term.h>
#elif defined HAVE_NCURSES_CURSES_H
#  include <ncurses/curses.h>
#  include <ncurses/term.h>
#elif defined HAVE_NCURSES_H
#  include <ncurses.h>
#  include <term.h>
#elif defined HAVE_CURSES_H
#  include <curses.h>
#  include <term.h>
#else
#  error "SysV or X/Open-compatible Curses header file required"
#endif

using namespace std;

/**
 * Singleton used to hold the mapping of ncurses keycodes to VT52 escape
 * sequences.
 */
class vt52_escape_map {
public:

    /** @return The singleton. */
    static vt52_escape_map &singleton()
    {
        static vt52_escape_map s_vem;

        return s_vem;
    };

    /**
     * @param ch The ncurses keycode.
     * @return The null terminated VT52 escape sequence.
     */
    const char *operator[](int ch) const
    {
        map<int, const char *>::const_iterator iter;
        const char *retval = NULL;

        if ((iter = this->vem_map.find(ch)) != this->vem_map.end()) {
            retval = iter->second;
        }

        return retval;
    };

    const char *operator[](const char *seq) const
    {
        map<string, const char *>::const_iterator iter;
        const char *retval = NULL;

        require(seq != NULL);

        if ((iter = this->vem_input_map.find(seq)) !=
            this->vem_input_map.end()) {
            retval = iter->second;
        }

        return retval;
    };

private:

    /** Construct the map with a few escape sequences. */
    vt52_escape_map()
    {
        static char area_buffer[1024];
        char *      area = area_buffer;

        if (tgetent(NULL, "vt52") == ERR) {
            perror("tgetent");
        }
        this->vem_map[KEY_UP]        = tgetstr((char *)"ku", &area);
        this->vem_map[KEY_DOWN]      = tgetstr((char *)"kd", &area);
        this->vem_map[KEY_RIGHT]     = tgetstr((char *)"kr", &area);
        this->vem_map[KEY_LEFT]      = tgetstr((char *)"kl", &area);
        this->vem_map[KEY_HOME]      = tgetstr((char *)"kh", &area);
        this->vem_map[KEY_BACKSPACE] = "\010";
        this->vem_map[KEY_DC]        = "\x4";

        this->vem_map[KEY_BEG] = "\x1";
        this->vem_map[KEY_END] = "\x5";

        this->vem_map[KEY_SLEFT] = tgetstr((char *)"#4", &area);
        if (this->vem_map[KEY_SLEFT] == NULL) {
            this->vem_map[KEY_SLEFT] = "\033b";
        }
        this->vem_map[KEY_SRIGHT] = tgetstr((char *)"%i", &area);
        if (this->vem_map[KEY_SRIGHT] == NULL) {
            this->vem_map[KEY_SRIGHT] = "\033f";
        }

        this->vem_input_map[tgetstr((char *)"ce", &area)] = "ce";
        this->vem_input_map[tgetstr((char *)"kl", &area)] = "kl";
        this->vem_input_map[tgetstr((char *)"kr", &area)] = "kr";
        tgetent(NULL, getenv("TERM"));
    };

    /** Map of ncurses keycodes to VT52 escape sequences. */
    map<int, const char *>    vem_map;
    map<string, const char *> vem_input_map;
};

vt52_curses::vt52_curses()
    : vc_window(NULL),
      vc_x(0),
      vc_y(0),
      vc_max_height(0),
      vc_escape_len(0),
      vc_map_buffer(0)
{ }

vt52_curses::~vt52_curses()
{ }

const char *vt52_curses::map_input(int ch, int &len_out)
{
    const char *esc, *retval;

    /* Check for an escape sequence, otherwise just return the char. */
    if ((esc = vt52_escape_map::singleton()[ch]) != NULL) {
        retval  = esc;
        len_out = strlen(retval);
    }
    else {
        this->vc_map_buffer = (char)ch;
        retval  = &this->vc_map_buffer; /* XXX probably shouldn't do this. */
        len_out = 1;
    }

    ensure(retval != NULL);
    ensure(len_out > 0);

    return retval;
}

void vt52_curses::map_output(const char *output, int len)
{
    int y, lpc;

    require(this->vc_window != NULL);

    y = this->get_actual_y();
    wmove(this->vc_window, y, this->vc_x);
    for (lpc = 0; lpc < len; lpc++) {
        if (this->vc_escape_len > 0) {
            const char *cap;

            this->vc_escape[this->vc_escape_len] = output[lpc];
            this->vc_escape_len += 1;
            this->vc_escape[this->vc_escape_len] = '\0';

            if ((cap = vt52_escape_map::singleton()[this->vc_escape]) !=
                NULL) {
                if (strcmp(cap, "ce") == 0) {
                    wclrtoeol(this->vc_window);
                    this->vc_escape_len = 0;
                }
                else if (strcmp(cap, "kl") == 0) {
                    this->vc_x -= 1;
                    wmove(this->vc_window, y, this->vc_x);
                    this->vc_escape_len = 0;
                }
                else if (strcmp(cap, "kr") == 0) {
                    this->vc_x += 1;
                    wmove(this->vc_window, y, this->vc_x);
                    this->vc_escape_len = 0;
                }
                else {
                    ensure(0);
                }
            }
        }
        else {
            switch (output[lpc]) {
            case STX:
                this->vc_past_lines.clear();
                this->vc_x = 0;
                wmove(this->vc_window, y, this->vc_x);
                wclrtoeol(this->vc_window);
                break;

            case BELL:
                flash();
                break;

            case BACKSPACE:
                this->vc_x -= 1;
                wmove(this->vc_window, y, this->vc_x);
                break;

            case ESCAPE:
                this->vc_escape[0]  = ESCAPE;
                this->vc_escape_len = 1;
                break;

            case '\n':
            {
                unsigned long width, height;
                char *        buffer;

                getmaxyx(this->vc_window, height, width);
                (void)height; //suppress unused warnings.

                buffer     = (char *)alloca(width);
                this->vc_x = 0;
                wmove(this->vc_window, y, this->vc_x);

                /*
                 * XXX Not sure why we need to subtract one from the width
                 * here, but otherwise it seems to spill over and screw up
                 * the next line when we're writing it back out in
                 * do_update().
                 */
                winnstr(this->vc_window, buffer, width - 1);
                this->vc_past_lines.push_back(buffer);
                wclrtoeol(this->vc_window);
            }
            break;

            case '\r':
                this->vc_x = 0;
                wmove(this->vc_window, y, this->vc_x);
                break;

            default:
                mvwaddch(this->vc_window, y, this->vc_x, output[lpc]);
                this->vc_x += 1;
                break;
            }
        }
    }
}

void vt52_curses::do_update(void)
{
    list<string>::iterator iter;
    int y;

    y = this->get_actual_y() - (int)this->vc_past_lines.size();
    for (iter = this->vc_past_lines.begin();
         iter != this->vc_past_lines.end();
         ++iter, y++) {
        if (y >= 0) {
            mvwprintw(this->vc_window, y, 0, "%s", iter->c_str());
            wclrtoeol(this->vc_window);
        }
    }
    wmove(this->vc_window, y, this->vc_x);
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2017, Timothy Stack
 *
 * 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 Timothy Stack 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 REGENTS 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 REGENTS 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.
 */

#ifndef __vtab_module_hh
#define __vtab_module_hh

#include <sqlite3.h>

#include <string>
#include <utility>

#include "lnav_log.hh"

template<typename T>
inline T from_sqlite(sqlite3_value *val)
{
    return T();
}

template<>
inline int64_t from_sqlite<int64_t>(sqlite3_value *val)
{
    return sqlite3_value_int64(val);
}

template<>
inline const char *from_sqlite<const char *>(sqlite3_value *val)
{
    return (const char *) sqlite3_value_text(val);
}

template<>
inline double from_sqlite<double>(sqlite3_value *val)
{
    return sqlite3_value_double(val);
}

extern std::string vtab_module_schemas;

template<typename T>
struct vtab_module {
    static int tvt_create(sqlite3 *db,
                          void *pAux,
                          int argc, const char *const *argv,
                          sqlite3_vtab **pp_vt,
                          char **pzErr) {
        static typename T::vtab vt;

        *pp_vt = vt;

        return sqlite3_declare_vtab(db, T::CREATE_STMT);
    };

    template<typename ... Args, size_t... Idx>
    static int apply_impl(T &obj, int (T::*func)(sqlite3_vtab *, sqlite3_int64 &, Args...), sqlite3_vtab *tab, sqlite3_int64 &rowid, sqlite3_value **argv, std::index_sequence<Idx...>)
    {
        return (obj.*func)(tab, rowid, from_sqlite<Args>(argv[Idx])...);
    }

    template<typename ... Args>
    static int apply(T &obj,
                     int (T::*func)(sqlite3_vtab *, sqlite3_int64 &, Args...),
                     sqlite3_vtab *tab,
                     sqlite3_int64 &rowid,
                     int argc,
                     sqlite3_value **argv)
    {
        require(sizeof...(Args) == 0 || argc == sizeof...(Args));

        return apply_impl(obj,
                          func,
                          tab,
                          rowid,
                          argv,
                          std::make_index_sequence<sizeof...(Args)>{});
    }

    static int tvt_destructor(sqlite3_vtab *p_svt)
    {
        return SQLITE_OK;
    }

    static int tvt_open(sqlite3_vtab *p_svt, sqlite3_vtab_cursor **pp_cursor)
    {
        p_svt->zErrMsg = NULL;

        typename T::cursor *p_cur = new (typename T::cursor)(p_svt);

        if (p_cur == NULL) {
            return SQLITE_NOMEM;
        } else {
            *pp_cursor = (sqlite3_vtab_cursor *) p_cur;
        }

        return SQLITE_OK;
    }

    static int tvt_next(sqlite3_vtab_cursor *cur)
    {
        typename T::cursor *p_cur = (typename T::cursor *) cur;

        return p_cur->next();
    }

    static int tvt_eof(sqlite3_vtab_cursor *cur)
    {
        typename T::cursor *p_cur = (typename T::cursor *) cur;

        return p_cur->eof();
    }

    static int tvt_close(sqlite3_vtab_cursor *cur)
    {
        typename T::cursor *p_cur = (typename T::cursor *) cur;

        delete p_cur;

        return SQLITE_OK;
    }

    static int tvt_rowid(sqlite3_vtab_cursor *cur, sqlite_int64 *p_rowid) {
        typename T::cursor *p_cur = (typename T::cursor *) cur;

        return p_cur->get_rowid(*p_rowid);
    };

    static int tvt_column(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int col) {
        typename T::cursor *p_cur = (typename T::cursor *) cur;
        T handler;

        return handler.get_column(*p_cur, ctx, col);
    };

    static int vt_best_index(sqlite3_vtab *tab, sqlite3_index_info *p_info) {
        return SQLITE_OK;
    };

    static int vt_filter(sqlite3_vtab_cursor *p_vtc,
                         int idxNum, const char *idxStr,
                         int argc, sqlite3_value **argv) {
        return SQLITE_OK;
    }

    static int tvt_update(sqlite3_vtab *tab,
                          int argc,
                          sqlite3_value **argv,
                          sqlite_int64 *rowid) {
        T handler;

        if (argc <= 1) {
            sqlite3_int64 rowid = sqlite3_value_int64(argv[0]);

            return handler.delete_row(tab, rowid);
        }

        if (sqlite3_value_type(argv[0]) == SQLITE_NULL) {
            sqlite3_int64 *rowid2 = rowid;
            return vtab_module<T>::apply(handler, &T::insert_row, tab, *rowid2, argc - 2, argv + 2);
        }

        sqlite3_int64 index = sqlite3_value_int64(argv[0]);

        if (index != sqlite3_value_int64(argv[1])) {
            tab->zErrMsg = sqlite3_mprintf(
                "The rowids in the lnav_views table cannot be changed");
            return SQLITE_ERROR;
        }

        return vtab_module<T>::apply(handler, &T::update_row, tab, index, argc - 2, argv + 2);
    };

    vtab_module() noexcept {
        memset(&this->vm_module, 0, sizeof(this->vm_module));
        this->vm_module.iVersion = 0;
        this->vm_module.xCreate = tvt_create;
        this->vm_module.xConnect = tvt_create;
        this->vm_module.xOpen = tvt_open;
        this->vm_module.xNext = tvt_next;
        this->vm_module.xEof = tvt_eof;
        this->vm_module.xClose = tvt_close;
        this->vm_module.xDestroy = tvt_destructor;
        this->vm_module.xRowid = tvt_rowid;
        this->vm_module.xDisconnect = tvt_destructor;
        this->vm_module.xBestIndex = vt_best_index;
        this->vm_module.xFilter = vt_filter;
        this->vm_module.xColumn = tvt_column;
        this->vm_module.xUpdate = tvt_update;
    };

    int create(sqlite3 *db, const char *name) {
        vtab_module_schemas += T::CREATE_STMT;

        return sqlite3_create_module(db, name, &this->vm_module, NULL);
    };

    sqlite3_module vm_module;
};

template<typename T>
struct tvt_iterator_cursor {
    struct cursor {
        sqlite3_vtab_cursor base;
        typename T::iterator iter;

        cursor(sqlite3_vtab *vt) {
            T handler;

            this->base.pVtab = vt;
            this->iter = handler.begin();
        };

        int next() {
            T handler;

            if (this->iter != handler.end()) {
                ++this->iter;
            }

            return SQLITE_OK;
        };

        int eof() {
            T handler;

            return this->iter == handler.end();
        };

        int get_rowid(sqlite_int64 &rowid_out) {
            T handler;

            rowid_out = std::distance(handler.begin(), this->iter);

            return SQLITE_OK;
        };
    };
};

template<typename T>
struct tvt_no_update : public T {
    int delete_row(sqlite3_vtab *vt, sqlite3_int64 rowid) {
        vt->zErrMsg = sqlite3_mprintf(
            "Rows cannot be deleted from this table");
        return SQLITE_ERROR;
    };

    int insert_row(sqlite3_vtab *tab, sqlite3_int64 &rowid_out) {
        tab->zErrMsg = sqlite3_mprintf(
            "Rows cannot be inserted into this table");
        return SQLITE_ERROR;
    };

    int update_row(sqlite3_vtab *tab, sqlite3_int64 &rowid_out) {
        tab->zErrMsg = sqlite3_mprintf(
            "Rows cannot be update in this table");
        return SQLITE_ERROR;
    };

};

#endif
<commit_msg>[sql] try to fix issue with eponymous tables on older sqlite versions<commit_after>/**
 * Copyright (c) 2017, Timothy Stack
 *
 * 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 Timothy Stack 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 REGENTS 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 REGENTS 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.
 */

#ifndef __vtab_module_hh
#define __vtab_module_hh

#include <sqlite3.h>

#include <string>
#include <utility>

#include "lnav_log.hh"

template<typename T>
inline T from_sqlite(sqlite3_value *val)
{
    return T();
}

template<>
inline int64_t from_sqlite<int64_t>(sqlite3_value *val)
{
    return sqlite3_value_int64(val);
}

template<>
inline const char *from_sqlite<const char *>(sqlite3_value *val)
{
    return (const char *) sqlite3_value_text(val);
}

template<>
inline double from_sqlite<double>(sqlite3_value *val)
{
    return sqlite3_value_double(val);
}

extern std::string vtab_module_schemas;

template<typename T>
struct vtab_module {
    static int tvt_create(sqlite3 *db,
                          void *pAux,
                          int argc, const char *const *argv,
                          sqlite3_vtab **pp_vt,
                          char **pzErr) {
        static typename T::vtab vt;

        *pp_vt = vt;

        return sqlite3_declare_vtab(db, T::CREATE_STMT);
    };

    template<typename ... Args, size_t... Idx>
    static int apply_impl(T &obj, int (T::*func)(sqlite3_vtab *, sqlite3_int64 &, Args...), sqlite3_vtab *tab, sqlite3_int64 &rowid, sqlite3_value **argv, std::index_sequence<Idx...>)
    {
        return (obj.*func)(tab, rowid, from_sqlite<Args>(argv[Idx])...);
    }

    template<typename ... Args>
    static int apply(T &obj,
                     int (T::*func)(sqlite3_vtab *, sqlite3_int64 &, Args...),
                     sqlite3_vtab *tab,
                     sqlite3_int64 &rowid,
                     int argc,
                     sqlite3_value **argv)
    {
        require(sizeof...(Args) == 0 || argc == sizeof...(Args));

        return apply_impl(obj,
                          func,
                          tab,
                          rowid,
                          argv,
                          std::make_index_sequence<sizeof...(Args)>{});
    }

    static int tvt_destructor(sqlite3_vtab *p_svt)
    {
        return SQLITE_OK;
    }

    static int tvt_open(sqlite3_vtab *p_svt, sqlite3_vtab_cursor **pp_cursor)
    {
        p_svt->zErrMsg = NULL;

        typename T::cursor *p_cur = new (typename T::cursor)(p_svt);

        if (p_cur == NULL) {
            return SQLITE_NOMEM;
        } else {
            *pp_cursor = (sqlite3_vtab_cursor *) p_cur;
        }

        return SQLITE_OK;
    }

    static int tvt_next(sqlite3_vtab_cursor *cur)
    {
        typename T::cursor *p_cur = (typename T::cursor *) cur;

        return p_cur->next();
    }

    static int tvt_eof(sqlite3_vtab_cursor *cur)
    {
        typename T::cursor *p_cur = (typename T::cursor *) cur;

        return p_cur->eof();
    }

    static int tvt_close(sqlite3_vtab_cursor *cur)
    {
        typename T::cursor *p_cur = (typename T::cursor *) cur;

        delete p_cur;

        return SQLITE_OK;
    }

    static int tvt_rowid(sqlite3_vtab_cursor *cur, sqlite_int64 *p_rowid) {
        typename T::cursor *p_cur = (typename T::cursor *) cur;

        return p_cur->get_rowid(*p_rowid);
    };

    static int tvt_column(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int col) {
        typename T::cursor *p_cur = (typename T::cursor *) cur;
        T handler;

        return handler.get_column(*p_cur, ctx, col);
    };

    static int vt_best_index(sqlite3_vtab *tab, sqlite3_index_info *p_info) {
        return SQLITE_OK;
    };

    static int vt_filter(sqlite3_vtab_cursor *p_vtc,
                         int idxNum, const char *idxStr,
                         int argc, sqlite3_value **argv) {
        return SQLITE_OK;
    }

    static int tvt_update(sqlite3_vtab *tab,
                          int argc,
                          sqlite3_value **argv,
                          sqlite_int64 *rowid) {
        T handler;

        if (argc <= 1) {
            sqlite3_int64 rowid = sqlite3_value_int64(argv[0]);

            return handler.delete_row(tab, rowid);
        }

        if (sqlite3_value_type(argv[0]) == SQLITE_NULL) {
            sqlite3_int64 *rowid2 = rowid;
            return vtab_module<T>::apply(handler, &T::insert_row, tab, *rowid2, argc - 2, argv + 2);
        }

        sqlite3_int64 index = sqlite3_value_int64(argv[0]);

        if (index != sqlite3_value_int64(argv[1])) {
            tab->zErrMsg = sqlite3_mprintf(
                "The rowids in the lnav_views table cannot be changed");
            return SQLITE_ERROR;
        }

        return vtab_module<T>::apply(handler, &T::update_row, tab, index, argc - 2, argv + 2);
    };

    vtab_module() noexcept {
        memset(&this->vm_module, 0, sizeof(this->vm_module));
        this->vm_module.iVersion = 0;
        this->vm_module.xCreate = tvt_create;
        this->vm_module.xConnect = tvt_create;
        this->vm_module.xOpen = tvt_open;
        this->vm_module.xNext = tvt_next;
        this->vm_module.xEof = tvt_eof;
        this->vm_module.xClose = tvt_close;
        this->vm_module.xDestroy = tvt_destructor;
        this->vm_module.xRowid = tvt_rowid;
        this->vm_module.xDisconnect = tvt_destructor;
        this->vm_module.xBestIndex = vt_best_index;
        this->vm_module.xFilter = vt_filter;
        this->vm_module.xColumn = tvt_column;
        this->vm_module.xUpdate = tvt_update;
    };

    int create(sqlite3 *db, const char *name) {
        std::string impl_name = name;
        vtab_module_schemas += T::CREATE_STMT;

        // XXX Eponymous tables don't seem to work in older sqlite versions
        impl_name += "_impl";
        int rc = sqlite3_create_module(db, impl_name.c_str(), &this->vm_module, NULL);
        std::string create_stmt = std::string("CREATE VIRTUAL TABLE ") + name + " USING " + impl_name + "()";
        return sqlite3_exec(db, create_stmt.c_str(), NULL, NULL, NULL);
    };

    sqlite3_module vm_module;
};

template<typename T>
struct tvt_iterator_cursor {
    struct cursor {
        sqlite3_vtab_cursor base;
        typename T::iterator iter;

        cursor(sqlite3_vtab *vt) {
            T handler;

            this->base.pVtab = vt;
            this->iter = handler.begin();
        };

        int next() {
            T handler;

            if (this->iter != handler.end()) {
                ++this->iter;
            }

            return SQLITE_OK;
        };

        int eof() {
            T handler;

            return this->iter == handler.end();
        };

        int get_rowid(sqlite_int64 &rowid_out) {
            T handler;

            rowid_out = std::distance(handler.begin(), this->iter);

            return SQLITE_OK;
        };
    };
};

template<typename T>
struct tvt_no_update : public T {
    int delete_row(sqlite3_vtab *vt, sqlite3_int64 rowid) {
        vt->zErrMsg = sqlite3_mprintf(
            "Rows cannot be deleted from this table");
        return SQLITE_ERROR;
    };

    int insert_row(sqlite3_vtab *tab, sqlite3_int64 &rowid_out) {
        tab->zErrMsg = sqlite3_mprintf(
            "Rows cannot be inserted into this table");
        return SQLITE_ERROR;
    };

    int update_row(sqlite3_vtab *tab, sqlite3_int64 &rowid_out) {
        tab->zErrMsg = sqlite3_mprintf(
            "Rows cannot be update in this table");
        return SQLITE_ERROR;
    };

};

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: msfiltertracer.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-04-11 16:00:48 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _MS_FILTERTRACER_HXX
#define _MS_FILTERTRACER_HXX

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif
#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif
#ifndef _XMLOFF_ATTRLIST_HXX
#include <xmloff/attrlist.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif
#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _COM_SUN_STAR_UTIL_XTEXTSEARCH_HPP_
#include <com/sun/star/util/XTextSearch.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_SEARCHRESULT_HPP_
#include <com/sun/star/util/SearchResult.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_LOGGING_XLOGGER_HPP_
#include <com/sun/star/util/logging/XLogger.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_XML_SAX_XATTRIBUTELIST_HPP_
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#endif
#ifndef _COM_SUN_STAR_XML_SAX_XDOCUMENTHANDLER_HPP_
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

class FilterConfigItem;
class SVX_DLLPUBLIC MSFilterTracer
{
        FilterConfigItem*   mpCfgItem;
        SvXMLAttributeList* mpAttributeList;
        SvStream*           mpStream;
        sal_Bool            mbEnabled;

        ::com::sun::star::util::SearchOptions maSearchOptions;
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >               mxFilterTracer;
        ::com::sun::star::uno::Reference< ::com::sun::star::util::XTextSearch >             mxTextSearch;

        ::com::sun::star::uno::Reference< ::com::sun::star::util::logging::XLogger >        mxLogger;
        ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler >    mxHandler;

    public :

        /* The first parameter is expecting the path of the configuration file.
           The second parameter can be used to override properties of the configuration
           file. A "DocumentURL" property can be set in the property
           sequence to provide the current url of the document.
           If the "Path" property is not set in the configuration file, then the path
           of the "DocumentURL" property is used instead. If both are not set, the
           application path is used instead.
           If the "Name" property is not set in the configuration file, then the name
           of the "DocumentURL" property is used instead. If both are not set, the
           name "tracer* is used.
           The file extension will always be "log" */

        MSFilterTracer( const ::rtl::OUString& rConfigurationPath,
            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pConfigData = NULL );
        ~MSFilterTracer();

        void StartTracing();
        void EndTracing();

        inline sal_Bool IsEnabled() const { return mbEnabled; }

        void StartElement( const ::rtl::OUString& rName, ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > xAttribs );
        void EndElement( const ::rtl::OUString& rName );

        void Trace( const ::rtl::OUString& rElementID, const ::rtl::OUString& rMessage );
        void AddAttribute( const ::rtl::OUString &sName , const ::rtl::OUString &sValue );
        void RemoveAttribute( const ::rtl::OUString& sName );
        void ClearAttributes();

        /* initially all properties of the configuration file and the
           properties which are given to the c'tor can be retrieved */
        ::com::sun::star::uno::Any GetProperty( const ::rtl::OUString& rPropName, const ::com::sun::star::uno::Any* pDefault = NULL ) const;
        void SetProperty( const ::rtl::OUString& rPropName, const ::com::sun::star::uno::Any& rProperty );
};

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.2.466); FILE MERGED 2008/04/01 15:49:34 thb 1.2.466.3: #i85898# Stripping all external header guards 2008/04/01 12:46:44 thb 1.2.466.2: #i85898# Stripping all external header guards 2008/03/31 14:18:13 rt 1.2.466.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: msfiltertracer.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _MS_FILTERTRACER_HXX
#define _MS_FILTERTRACER_HXX

#include <rtl/ustring.hxx>
#include <tools/stream.hxx>
#include <xmloff/attrlist.hxx>
#include <com/sun/star/uno/Any.h>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/util/XTextSearch.hpp>
#include <com/sun/star/util/SearchResult.hpp>
#include <com/sun/star/util/logging/XLogger.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include "svx/svxdllapi.h"

class FilterConfigItem;
class SVX_DLLPUBLIC MSFilterTracer
{
        FilterConfigItem*   mpCfgItem;
        SvXMLAttributeList* mpAttributeList;
        SvStream*           mpStream;
        sal_Bool            mbEnabled;

        ::com::sun::star::util::SearchOptions maSearchOptions;
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >               mxFilterTracer;
        ::com::sun::star::uno::Reference< ::com::sun::star::util::XTextSearch >             mxTextSearch;

        ::com::sun::star::uno::Reference< ::com::sun::star::util::logging::XLogger >        mxLogger;
        ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler >    mxHandler;

    public :

        /* The first parameter is expecting the path of the configuration file.
           The second parameter can be used to override properties of the configuration
           file. A "DocumentURL" property can be set in the property
           sequence to provide the current url of the document.
           If the "Path" property is not set in the configuration file, then the path
           of the "DocumentURL" property is used instead. If both are not set, the
           application path is used instead.
           If the "Name" property is not set in the configuration file, then the name
           of the "DocumentURL" property is used instead. If both are not set, the
           name "tracer* is used.
           The file extension will always be "log" */

        MSFilterTracer( const ::rtl::OUString& rConfigurationPath,
            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pConfigData = NULL );
        ~MSFilterTracer();

        void StartTracing();
        void EndTracing();

        inline sal_Bool IsEnabled() const { return mbEnabled; }

        void StartElement( const ::rtl::OUString& rName, ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > xAttribs );
        void EndElement( const ::rtl::OUString& rName );

        void Trace( const ::rtl::OUString& rElementID, const ::rtl::OUString& rMessage );
        void AddAttribute( const ::rtl::OUString &sName , const ::rtl::OUString &sValue );
        void RemoveAttribute( const ::rtl::OUString& sName );
        void ClearAttributes();

        /* initially all properties of the configuration file and the
           properties which are given to the c'tor can be retrieved */
        ::com::sun::star::uno::Any GetProperty( const ::rtl::OUString& rPropName, const ::com::sun::star::uno::Any* pDefault = NULL ) const;
        void SetProperty( const ::rtl::OUString& rPropName, const ::com::sun::star::uno::Any& rProperty );
};

#endif
<|endoftext|>