<commit_before>/**
\description The is the main for the new version of the mert algorithm develloppped during the 2nd MT marathon
*/

#include <limits>
#include "Data.h"
#include "Point.h"
#include "Scorer.h"
#include "ScoreData.h"
#include "FeatureData.h"
#include "Optimizer.h"
#include "getopt.h"
#include "Types.h"
#include <unistd.h>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cmath>
#include "Timer.h"
#include "Util.h"

float min_interval = 1e-3;

using namespace std;

void usage(void) {
  cerr<<"usage: mert -d <dimensions> (mandatory )"<<endl;
  cerr<<"[-n retry ntimes (default 1)]"<<endl;
  cerr<<"[-o\tthe indexes to optimize(default all)]"<<endl;
  cerr<<"[-t\tthe optimizer(default powell)]"<<endl;
  cerr<<"[--sctype|-s] the scorer type (default BLEU)"<<endl;
  cerr<<"[--scfile|-S] the scorer data file (default score.data)"<<endl;
  cerr<<"[--ffile|-F] the feature data file data file (default feature.data)"<<endl;
  cerr<<"[-v] verbose level"<<endl;
  exit(1);
}

static struct option long_options[] =
  {
    {"pdim", 1, 0, 'd'},
    {"ntry",1,0,'n'},
    {"optimize",1,0,'o'},
    {"type",1,0,'t'},
    {"sctype",1,0,'s'},
    {"scfile",1,0,'S'},
    {"ffile",1,0,'F'},
    {"verbose",1,0,'v'},
    {0, 0, 0, 0}
  };
int option_index;

int main (int argc, char **argv) {
  int c,pdim,i;
  pdim=-1;
  int ntry=1;
  string type("powell");
  string scorertype("BLEU");
  string scorerfile("statscore.data");
  string featurefile("features.data");
  vector<unsigned> tooptimize;
  vector<parameter_t> start;
  while ((c=getopt_long (argc, argv, "d:n:t:s:S:F:v:", long_options, &option_index)) != -1) {
    switch (c) {
    case 'd':
      pdim = strtol(optarg, NULL, 10);
      break;
    case 'n':
      ntry=strtol(optarg, NULL, 10);
      break;
    case 't':
      type=string(optarg);
      break;
      case's':
	scorertype=string(optarg);
      break;
    case 'S':
      scorerfile=string(optarg);
    case 'F':
      featurefile=string(optarg);
      break;
    case 'v':
      setverboselevel(strtol(optarg,NULL,10));
      break;
    default:
      usage();
    }
  }
  if (pdim < 0)
    usage();

  Timer timer;
  timer.start("Starting...");

  if(tooptimize.empty()){
    tooptimize.resize(pdim);//We'll optimize on everything
    for(i=0;i<pdim;i++)
      tooptimize[i]=i;
  }
  ifstream opt("init.opt");
  if(opt.fail()){
    cerr<<"could not open init.opt"<<endl;
    exit(3);
  }
  start.resize(pdim);//to do:read from file
  int j;
  for( j=0;j<pdim&&!opt.fail();j++)
    opt>>start[j];
  if(j<pdim){
    cerr<<"error could not initialize start point with init.opt"<<endl;
    exit(3);
  }

  opt.close();
  //it make sense to know what parameter set were used to generate the nbest
  ScorerFactory SF;
  Scorer *TheScorer=SF.getScorer(scorertype);
  ScoreData *SD=new ScoreData(*TheScorer);
  SD->load(scorerfile);
  FeatureData *FD=new FeatureData();
  FD->load(featurefile);
  Optimizer *O=OptimizerFactory::BuildOptimizer(pdim,tooptimize,start,type);
  O->SetScorer(TheScorer);
  O->SetFData(FD);
  Point P(start);//Generate from the full feature set. Warning: must ne done after Optimiezr initialiazation
  statscore_t best=O->Run(P);
  Point bestP=P;
  statscore_t mean=best;
  statscore_t var=best*best;

  vector<parameter_t> min(Point::getdim());
  vector<parameter_t> max(Point::getdim());

 for(int d=0;d<Point::getdim();d++){
    min[d]=0.0;
    max[d]=1.0;
  }
  //note: those mins and max are the bound for the starting points of the algorithm, not strict bound on the result!

 for(int i=1;i<ntry;i++){
   P.Randomize(min,max);
   statscore_t score=O->Run(P);
   if(score>best){
     best=score;
     bestP=P;
  }
   mean+=score;
   var+=(score*score);
 }
 mean/=(float)ntry;
 var/=(float)ntry;
 var=sqrt(abs(var-mean*mean));
 if(ntry>1)
   cerr<<"variance of the score (for "<<ntry<<" try):"<<var<<endl;
 cerr<<"best score"<<best<<endl;
 ofstream res("weights.txt");
 res<<bestP<<endl;
 timer.stop("Stopping...");
}
<commit_msg>I fixed a small bug when reading parameters<commit_after>/**
\description The is the main for the new version of the mert algorithm develloppped during the 2nd MT marathon
*/

#include <limits>
#include "Data.h"
#include "Point.h"
#include "Scorer.h"
#include "ScoreData.h"
#include "FeatureData.h"
#include "Optimizer.h"
#include "getopt.h"
#include "Types.h"
#include <unistd.h>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cmath>
#include "Timer.h"
#include "Util.h"

float min_interval = 1e-3;

using namespace std;

void usage(void) {
  cerr<<"usage: mert -d <dimensions> (mandatory )"<<endl;
  cerr<<"[-n retry ntimes (default 1)]"<<endl;
  cerr<<"[-o\tthe indexes to optimize(default all)]"<<endl;
  cerr<<"[-t\tthe optimizer(default powell)]"<<endl;
  cerr<<"[--sctype|-s] the scorer type (default BLEU)"<<endl;
  cerr<<"[--scfile|-S] the scorer data file (default score.data)"<<endl;
  cerr<<"[--ffile|-F] the feature data file data file (default feature.data)"<<endl;
  cerr<<"[-v] verbose level"<<endl;
  exit(1);
}

static struct option long_options[] =
  {
    {"pdim", 1, 0, 'd'},
    {"ntry",1,0,'n'},
    {"optimize",1,0,'o'},
    {"type",1,0,'t'},
    {"sctype",1,0,'s'},
    {"scfile",1,0,'S'},
    {"ffile",1,0,'F'},
    {"verbose",1,0,'v'},
    {0, 0, 0, 0}
  };
int option_index;

int main (int argc, char **argv) {
  int c,pdim,i;
  pdim=-1;
  int ntry=1;
  string type("powell");
  string scorertype("BLEU");
  string scorerfile("statscore.data");
  string featurefile("features.data");
  vector<unsigned> tooptimize;
  vector<parameter_t> start;
  while ((c=getopt_long (argc, argv, "d:n:t:s:S:F:v:", long_options, &option_index)) != -1) {
    switch (c) {
    case 'd':
      pdim = strtol(optarg, NULL, 10);
      break;
    case 'n':
      ntry=strtol(optarg, NULL, 10);
      break;
    case 't':
      type=string(optarg);
      break;
    case's':
      scorertype=string(optarg);
      break;
    case 'S':
      scorerfile=string(optarg);
      break;
    case 'F':
      featurefile=string(optarg);
      break;
    case 'v':
      setverboselevel(strtol(optarg,NULL,10));
      break;
    default:
      usage();
    }
  }
  if (pdim < 0)
    usage();

  Timer timer;
  timer.start("Starting...");

  if(tooptimize.empty()){
    tooptimize.resize(pdim);//We'll optimize on everything
    for(i=0;i<pdim;i++)
      tooptimize[i]=i;
  }
  ifstream opt("init.opt");
  if(opt.fail()){
    cerr<<"could not open init.opt"<<endl;
    exit(3);
  }
  start.resize(pdim);//to do:read from file
  int j;
  for( j=0;j<pdim&&!opt.fail();j++)
    opt>>start[j];
  if(j<pdim){
    cerr<<"error could not initialize start point with init.opt"<<endl;
    exit(3);
  }

  opt.close();
  //it make sense to know what parameter set were used to generate the nbest
  ScorerFactory SF;
  Scorer *TheScorer=SF.getScorer(scorertype);

  cerr<<"Loading ScoreData from: "<< scorerfile  << endl;
  ScoreData *SD=new ScoreData(*TheScorer);
  SD->load(scorerfile);

  cerr<<"Loading FeatureData from: "<< featurefile  << endl;
  FeatureData *FD=new FeatureData();
  FD->load(featurefile);
  Optimizer *O=OptimizerFactory::BuildOptimizer(pdim,tooptimize,start,type);
  O->SetScorer(TheScorer);
  O->SetFData(FD);
  Point P(start);//Generate from the full feature set. Warning: must ne done after Optimiezr initialiazation
  statscore_t best=O->Run(P);
  Point bestP=P;
  statscore_t mean=best;
  statscore_t var=best*best;

  vector<parameter_t> min(Point::getdim());
  vector<parameter_t> max(Point::getdim());

 for(int d=0;d<Point::getdim();d++){
    min[d]=0.0;
    max[d]=1.0;
  }
  //note: those mins and max are the bound for the starting points of the algorithm, not strict bound on the result!

 for(int i=1;i<ntry;i++){
   P.Randomize(min,max);
   statscore_t score=O->Run(P);
   if(score>best){
     best=score;
     bestP=P;
  }
   mean+=score;
   var+=(score*score);
 }
 mean/=(float)ntry;
 var/=(float)ntry;
 var=sqrt(abs(var-mean*mean));
 if(ntry>1)
   cerr<<"variance of the score (for "<<ntry<<" try):"<<var<<endl;
 cerr<<"best score"<<best<<endl;
 ofstream res("weights.txt");
 res<<bestP<<endl;
 timer.stop("Stopping...");
}
<|endoftext|>


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

#include <pangolin/video/drivers/join.h>

namespace pangolin
{
VideoJoiner::VideoJoiner(const std::vector<VideoInterface*>& src)
    : src(src), size_bytes(0), sync_attempts_to_go(-1), sync_continuously(false)
{
    // Add individual streams
    for(size_t s=0; s< src.size(); ++s)
    {
        VideoInterface& vid = *src[s];
        for(size_t i=0; i < vid.Streams().size(); ++i)
        {
            const StreamInfo si = vid.Streams()[i];
            const VideoPixelFormat fmt = si.PixFormat();
            const Image<unsigned char> img_offset = si.StreamImage((unsigned char*)size_bytes);
            streams.push_back(StreamInfo(fmt, img_offset));
        }
        size_bytes += src[s]->SizeBytes();
    }
}

VideoJoiner::~VideoJoiner()
{
    for(size_t s=0; s< src.size(); ++s) {
        src[s]->Stop();
        delete src[s];
    }
}

size_t VideoJoiner::SizeBytes() const
{
    return size_bytes;
}

const std::vector<StreamInfo>& VideoJoiner::Streams() const
{
    return streams;
}

void VideoJoiner::Start()
{
    for(size_t s=0; s< src.size(); ++s) {
        src[s]->Start();
    }
}

void VideoJoiner::Stop()
{
    for(size_t s=0; s< src.size(); ++s) {
        src[s]->Stop();
    }
}

bool VideoJoiner::Sync(int64_t tolerance_us, bool continuous)
{
    for(size_t s=0; s< src.size(); ++s)
    {
       VideoPropertiesInterface* vpi = dynamic_cast<VideoPropertiesInterface*>(src[s]);
       if(!vpi)
         return false;
    }
    sync_attempts_to_go = MAX_SYNC_ATTEMPTS;
    sync_tolerance_us = tolerance_us;
    sync_continuously = continuous;
    return true;
}

bool VideoJoiner::GrabNext( unsigned char* image, bool wait )
{
    size_t offset = 0;
    std::vector<size_t> offsets;
    std::vector<int64_t> reception_times;
    int64_t newest = std::numeric_limits<int64_t>::min();
    int64_t oldest = std::numeric_limits<int64_t>::max();
    bool grabbed_any = false;

    for(size_t s=0; s<src.size(); ++s) {
       VideoInterface& vid = *src[s];
       grabbed_any |= vid.GrabNext(image+offset,wait);
       offsets.push_back(offset);
       offset += vid.SizeBytes();
       if(sync_attempts_to_go >= 0) {
          VideoPropertiesInterface* vidpi = dynamic_cast<VideoPropertiesInterface*>(src[s]);
          if(vidpi->FrameProperties().contains(PANGO_HOST_RECEPTION_TIME_US)) {
             int64_t rt = vidpi->FrameProperties()[PANGO_HOST_RECEPTION_TIME_US].get<int64_t>();
             reception_times.push_back(rt);
             if(newest < rt) newest = rt;
             if(oldest > rt) oldest = rt;
          } else {
             sync_attempts_to_go = -1;
             pango_print_error("Stream %lu in join does not support startup_sync_us option.\n", s);
          }
       }
    }

    if((sync_continuously || (sync_attempts_to_go == 0)) && ((newest - oldest) > sync_tolerance_us) ){
       pango_print_warn("Join error, unable to sync streams within %lu us\n", (unsigned long)sync_tolerance_us);
    }

    if(sync_attempts_to_go >= 0) {
       for(size_t s=0; s<src.size(); ++s) {
          if(reception_times[s] < (newest - sync_tolerance_us)) {
             VideoInterface& vid = *src[s];
             vid.GrabNewest(image+offsets[s],false);
          }
       }
       if(!sync_continuously) --sync_attempts_to_go;
    }

    return grabbed_any;
}

bool VideoJoiner::GrabNewest( unsigned char* image, bool wait )
{
  // Simply calling GrabNewest on the child streams might cause loss of sync,
  // instead we perform as many GrabNext as possible on the first stream and
  // then pull the same number of frames from every other stream.

  size_t offset = 0;
  std::vector<size_t> offsets;
  std::vector<int64_t> reception_times;
  int64_t newest = std::numeric_limits<int64_t>::min();
  int64_t oldest = std::numeric_limits<int64_t>::max();
  bool grabbed_any = false;
  int first_stream_backlog = 0;
  int64_t rt = 0;

  bool got_frame = false;
  do {
      got_frame = src[0]->GrabNext(image+offset,false);
      if(got_frame) {
          if(sync_attempts_to_go >= 0) {
              VideoPropertiesInterface* vidpi = dynamic_cast<VideoPropertiesInterface*>(src[0]);
              if(vidpi->FrameProperties().contains(PANGO_HOST_RECEPTION_TIME_US)) {
                  rt = vidpi->FrameProperties()[PANGO_HOST_RECEPTION_TIME_US].get<int64_t>();
              } else {
                  sync_attempts_to_go = -1;
                  pango_print_error("Stream %u in join does not support startup_sync_us option.\n", 0);
              }
          }
          first_stream_backlog++;
          grabbed_any = true;
      }
  } while(got_frame);
  offsets.push_back(offset);
  offset += src[0]->SizeBytes();
  if(sync_attempts_to_go >= 0) {
      reception_times.push_back(rt);
      if(newest < rt) newest = rt;
      if(oldest > rt) oldest = rt;
  }

  for(size_t s=1; s<src.size(); ++s) {
      for (int i=0; i<first_stream_backlog; i++){
          grabbed_any |= src[s]->GrabNext(image+offset,true);
          if(sync_attempts_to_go >= 0) {
              VideoPropertiesInterface* vidpi = dynamic_cast<VideoPropertiesInterface*>(src[s]);
              if(vidpi->FrameProperties().contains(PANGO_HOST_RECEPTION_TIME_US)) {
                  rt = vidpi->FrameProperties()[PANGO_HOST_RECEPTION_TIME_US].get<int64_t>();
              } else {
                  sync_attempts_to_go = -1;
                  pango_print_error("Stream %lu in join does not support startup_sync_us option.\n", s);
              }
          }
      }
      offsets.push_back(offset);
      offset += src[s]->SizeBytes();
      if(sync_attempts_to_go >= 0) {
          reception_times.push_back(rt);
          if(newest < rt) newest = rt;
          if(oldest > rt) oldest = rt;
      }
  }

  if((sync_continuously || (sync_attempts_to_go == 0)) && ((newest - oldest) > sync_tolerance_us) ){
     pango_print_warn("Join error, unable to sync streams within %lu us\n", (unsigned long)sync_tolerance_us);
  }

  if(sync_attempts_to_go >= 0) {
     for(size_t s=0; s<src.size(); ++s) {
        if(reception_times[s] < (newest - sync_tolerance_us)) {
           VideoInterface& vid = *src[s];
           vid.GrabNewest(image+offsets[s],false);
        }
     }
     if(!sync_continuously) --sync_attempts_to_go;
  }

  return grabbed_any;
}

std::vector<VideoInterface*>& VideoJoiner::InputStreams()
{
    return src;
}

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

#include <pangolin/video/drivers/join.h>
#include <pangolin/utils/timer.h>

namespace pangolin
{
VideoJoiner::VideoJoiner(const std::vector<VideoInterface*>& src)
    : src(src), size_bytes(0), sync_attempts_to_go(-1), sync_continuously(false)
{
    // Add individual streams
    for(size_t s=0; s< src.size(); ++s)
    {
        VideoInterface& vid = *src[s];
        for(size_t i=0; i < vid.Streams().size(); ++i)
        {
            const StreamInfo si = vid.Streams()[i];
            const VideoPixelFormat fmt = si.PixFormat();
            const Image<unsigned char> img_offset = si.StreamImage((unsigned char*)size_bytes);
            streams.push_back(StreamInfo(fmt, img_offset));
        }
        size_bytes += src[s]->SizeBytes();
    }
}

VideoJoiner::~VideoJoiner()
{
    for(size_t s=0; s< src.size(); ++s) {
        src[s]->Stop();
        delete src[s];
    }
}

size_t VideoJoiner::SizeBytes() const
{
    return size_bytes;
}

const std::vector<StreamInfo>& VideoJoiner::Streams() const
{
    return streams;
}

void VideoJoiner::Start()
{
    for(size_t s=0; s< src.size(); ++s) {
        src[s]->Start();
    }
}

void VideoJoiner::Stop()
{
    for(size_t s=0; s< src.size(); ++s) {
        src[s]->Stop();
    }
}

bool VideoJoiner::Sync(int64_t tolerance_us, bool continuous)
{
    for(size_t s=0; s< src.size(); ++s)
    {
       VideoPropertiesInterface* vpi = dynamic_cast<VideoPropertiesInterface*>(src[s]);
       if(!vpi)
         return false;
    }
    sync_attempts_to_go = MAX_SYNC_ATTEMPTS;
    sync_tolerance_us = tolerance_us;
    sync_continuously = continuous;
    return true;
}

bool VideoJoiner::GrabNext( unsigned char* image, bool wait )
{
    size_t offset = 0;
    std::vector<size_t> offsets;
    std::vector<int64_t> reception_times;
    int64_t newest = std::numeric_limits<int64_t>::min();
    int64_t oldest = std::numeric_limits<int64_t>::max();
    bool grabbed_any = false;

    for(size_t s=0; s<src.size(); ++s) {
       VideoInterface& vid = *src[s];
       grabbed_any |= vid.GrabNext(image+offset,wait);
       offsets.push_back(offset);
       offset += vid.SizeBytes();
       if(sync_attempts_to_go >= 0) {
          VideoPropertiesInterface* vidpi = dynamic_cast<VideoPropertiesInterface*>(src[s]);
          if(vidpi->FrameProperties().contains(PANGO_HOST_RECEPTION_TIME_US)) {
             int64_t rt = vidpi->FrameProperties()[PANGO_HOST_RECEPTION_TIME_US].get<int64_t>();
             reception_times.push_back(rt);
             if(newest < rt) newest = rt;
             if(oldest > rt) oldest = rt;
          } else {
             sync_attempts_to_go = -1;
             pango_print_error("Stream %lu in join does not support startup_sync_us option.\n", s);
          }
       }
    }

    if((sync_continuously || (sync_attempts_to_go == 0)) && ((newest - oldest) > sync_tolerance_us) ){
       pango_print_warn("Join error, unable to sync streams within %lu us\n", (unsigned long)sync_tolerance_us);
    }

    if(sync_attempts_to_go >= 0) {
       for(size_t s=0; s<src.size(); ++s) {
          if(reception_times[s] < (newest - sync_tolerance_us)) {
             VideoInterface& vid = *src[s];
             vid.GrabNewest(image+offsets[s],false);
          }
       }
       if(!sync_continuously) --sync_attempts_to_go;
    }

    return grabbed_any;
}

bool VideoJoiner::GrabNewest( unsigned char* image, bool wait )
{
  // Simply calling GrabNewest on the child streams might cause loss of sync,
  // instead we perform as many GrabNext as possible on the first stream and
  // then pull the same number of frames from every other stream.

  size_t offset = 0;
  std::vector<size_t> offsets;
  std::vector<int64_t> reception_times;
  int64_t newest = std::numeric_limits<int64_t>::min();
  int64_t oldest = std::numeric_limits<int64_t>::max();
  bool grabbed_any = false;
  int first_stream_backlog = 0;
  int64_t rt = 0;
  pangolin::basetime start,last,now;

  start = pangolin::TimeNow();
  last = start;
  bool got_frame = false;
  do {
      got_frame = src[0]->GrabNext(image+offset,false);
      if(got_frame) {
          if(sync_attempts_to_go >= 0) {
              VideoPropertiesInterface* vidpi = dynamic_cast<VideoPropertiesInterface*>(src[0]);
              if(vidpi->FrameProperties().contains(PANGO_HOST_RECEPTION_TIME_US)) {
                  rt = vidpi->FrameProperties()[PANGO_HOST_RECEPTION_TIME_US].get<int64_t>();
              } else {
                  sync_attempts_to_go = -1;
                  pango_print_error("Stream %u in join does not support startup_sync_us option.\n", 0);
              }
          }
          first_stream_backlog++;
          grabbed_any = true;
      }
  } while(got_frame);
  offsets.push_back(offset);
  offset += src[0]->SizeBytes();
  if(sync_attempts_to_go >= 0) {
      reception_times.push_back(rt);
      if(newest < rt) newest = rt;
      if(oldest > rt) oldest = rt;
  }
  now = pangolin::TimeNow();
  std::cout << "JOIN: Stream 1 grab: " << 1000*pangolin::TimeDiff_s(last, now) << "ms" << std::endl;
  last = now;

  for(size_t s=1; s<src.size(); ++s) {
      for (int i=0; i<first_stream_backlog; i++){
          grabbed_any |= src[s]->GrabNext(image+offset,true);
          if(sync_attempts_to_go >= 0) {
              VideoPropertiesInterface* vidpi = dynamic_cast<VideoPropertiesInterface*>(src[s]);
              if(vidpi->FrameProperties().contains(PANGO_HOST_RECEPTION_TIME_US)) {
                  rt = vidpi->FrameProperties()[PANGO_HOST_RECEPTION_TIME_US].get<int64_t>();
              } else {
                  sync_attempts_to_go = -1;
                  pango_print_error("Stream %lu in join does not support startup_sync_us option.\n", s);
              }
          }
      }
      offsets.push_back(offset);
      offset += src[s]->SizeBytes();
      if(sync_attempts_to_go >= 0) {
          reception_times.push_back(rt);
          if(newest < rt) newest = rt;
          if(oldest > rt) oldest = rt;
      }
  }
  now = pangolin::TimeNow();
  std::cout << "JOIN: Stream 2 grab: " << 1000*pangolin::TimeDiff_s(last, now) << "ms" << std::endl;
  last = now;

  if((sync_continuously || (sync_attempts_to_go == 0)) && ((newest - oldest) > sync_tolerance_us) ){
     pango_print_warn("Join error, unable to sync streams within %lu us\n", (unsigned long)sync_tolerance_us);
  }

  if(sync_attempts_to_go >= 0) {
     for(size_t s=0; s<src.size(); ++s) {
        if(reception_times[s] < (newest - sync_tolerance_us)) {
           VideoInterface& vid = *src[s];
           vid.GrabNewest(image+offsets[s],false);
        }
     }
     if(!sync_continuously) --sync_attempts_to_go;
  }
  now = pangolin::TimeNow();
  std::cout << "JOIN: Sync: " << 1000*pangolin::TimeDiff_s(last, now) << "ms" << std::endl;
  last = now;

  return grabbed_any;
}

std::vector<VideoInterface*>& VideoJoiner::InputStreams()
{
    return src;
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/ui/ui_layout_test.h"

#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/test/test_file_util.h"
#include "base/test/test_timeouts.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/automation/tab_proxy.h"
#include "net/base/escape.h"
#include "net/base/net_util.h"

#if defined(OS_WIN)
static const char kPlatformName[] = "chromium-win";
#elif defined(OS_MACOSX)
static const char kPlatformName[] = "chromium-mac";
#elif defined(OS_LINUX)
static const char kPlatformName[] = "chromium-linux";
#else
#error No known OS defined
#endif

static const char kTestCompleteCookie[] = "status";

UILayoutTest::UILayoutTest()
    : initialized_for_layout_test_(false),
      test_count_(0) {
}

UILayoutTest::~UILayoutTest() {
  if (!temp_test_dir_.empty()) {
    // The deletion might fail because HTTP server process might not been
    // completely shut down yet and is still holding certain handle to it.
    // To work around this problem, we try to repeat the deletion several
    // times.
    EXPECT_TRUE(file_util::DieFileDie(temp_test_dir_, true));
  }
}

void UILayoutTest::InitializeForLayoutTest(const FilePath& test_parent_dir,
                                           const FilePath& test_case_dir,
                                           int port) {
  FilePath src_dir;
  PathService::Get(base::DIR_SOURCE_ROOT, &src_dir);

  src_dir = src_dir.AppendASCII("chrome");
  src_dir = src_dir.AppendASCII("test");
  src_dir = src_dir.AppendASCII("data");
  src_dir = src_dir.AppendASCII("layout_tests");
  src_dir = src_dir.AppendASCII("LayoutTests");

  // Gets the file path to WebKit ui layout tests, that is,
  //   chrome/test/data/ui_tests/LayoutTests/...
  // Note that we have to use our own copy of WebKit layout tests because our
  // build machines do not have WebKit layout tests added.
  layout_test_dir_ = src_dir.Append(test_parent_dir);
  layout_test_dir_ = layout_test_dir_.Append(test_case_dir);
  ASSERT_TRUE(file_util::DirectoryExists(layout_test_dir_));

  // Gets the file path to rebased expected result directory for the current
  // platform.
  //   chrome/test/data/layout_tests/LayoutTests/platform/chromium_***/...
  rebase_result_dir_ = src_dir.AppendASCII("platform");
  rebase_result_dir_ = rebase_result_dir_.AppendASCII(kPlatformName);
  rebase_result_dir_ = rebase_result_dir_.Append(test_parent_dir);
  rebase_result_dir_ = rebase_result_dir_.Append(test_case_dir);

  // Generic chromium expected results. Not OS-specific. For example,
  // v8-specific differences go here.
  // chrome/test/data/layout_tests/LayoutTests/platform/chromium/...
  rebase_result_chromium_dir_ = src_dir.AppendASCII("platform")
                                       .AppendASCII("chromium")
                                       .Append(test_parent_dir)
                                       .Append(test_case_dir);

  // Gets the file path to rebased expected result directory under the
  // win32 platform. This is used by other non-win32 platform to use the same
  // rebased expected results.
#if !defined(OS_WIN)
  rebase_result_win_dir_ = src_dir.AppendASCII("platform")
                                  .AppendASCII("chromium-win")
                                  .Append(test_parent_dir)
                                  .Append(test_case_dir);
#endif

  // Creates the temporary directory.
  ASSERT_TRUE(file_util::CreateNewTempDirectory(
      FILE_PATH_LITERAL("chrome_ui_layout_tests_"), &temp_test_dir_));

  // Creates the new layout test subdirectory under the temp directory.
  // Note that we have to mimic the same layout test directory structure,
  // like .../LayoutTests/fast/workers/.... Otherwise those layout tests
  // dealing with location property, like worker-location.html, could fail.
  new_layout_test_dir_ = temp_test_dir_;
  new_layout_test_dir_ = new_layout_test_dir_.AppendASCII("LayoutTests");
  new_layout_test_dir_ = new_layout_test_dir_.Append(test_parent_dir);
  if (port == kHttpPort) {
    new_http_root_dir_ = new_layout_test_dir_;
    test_case_dir_ = test_case_dir;
  }
  new_layout_test_dir_ = new_layout_test_dir_.Append(test_case_dir);
  ASSERT_TRUE(file_util::CreateDirectory(new_layout_test_dir_));

  // Copy the resource subdirectory if it exists.
  FilePath layout_test_resource_path(layout_test_dir_);
  layout_test_resource_path =
      layout_test_resource_path.AppendASCII("resources");
  FilePath new_layout_test_resource_path(new_layout_test_dir_);
  new_layout_test_resource_path =
      new_layout_test_resource_path.AppendASCII("resources");
  file_util::CopyDirectory(layout_test_resource_path,
                           new_layout_test_resource_path, true);

  // Copies the parent resource subdirectory. This is needed in order to run
  // http layout tests.
  if (port == kHttpPort) {
    FilePath parent_resource_path(layout_test_dir_.DirName());
    parent_resource_path = parent_resource_path.AppendASCII("resources");
    FilePath new_parent_resource_path(new_layout_test_dir_.DirName());
    new_parent_resource_path =
        new_parent_resource_path.AppendASCII("resources");
    ASSERT_TRUE(file_util::CopyDirectory(
        parent_resource_path, new_parent_resource_path, true));
  }

  // Reads the layout test controller simulation script.
  FilePath path;
  PathService::Get(chrome::DIR_TEST_DATA, &path);
  path = path.AppendASCII("layout_tests");
  path = path.AppendASCII("layout_test_controller.html");
  ASSERT_TRUE(file_util::ReadFileToString(path, &layout_test_controller_));
}

void UILayoutTest::AddResourceForLayoutTest(const FilePath& parent_dir,
                                            const FilePath& resource_name) {
  FilePath root_dir;
  PathService::Get(base::DIR_SOURCE_ROOT, &root_dir);

  FilePath source = root_dir.AppendASCII("chrome");
  source = source.AppendASCII("test");
  source = source.AppendASCII("data");
  source = source.AppendASCII("layout_tests");
  source = source.AppendASCII("LayoutTests");
  source = source.Append(parent_dir);
  source = source.Append(resource_name);

  ASSERT_TRUE(file_util::PathExists(source));

  FilePath dest_parent_dir = temp_test_dir_.
      AppendASCII("LayoutTests").Append(parent_dir);
  ASSERT_TRUE(file_util::CreateDirectory(dest_parent_dir));
  FilePath dest = dest_parent_dir.Append(resource_name);

  if (file_util::DirectoryExists(source)) {
    ASSERT_TRUE(file_util::CopyDirectory(source, dest, true));
  } else {
    ASSERT_TRUE(file_util::CopyFile(source, dest));
  }
}

static size_t FindInsertPosition(const std::string& html) {
  size_t tag_start = html.find("<html");
  if (tag_start == std::string::npos)
    return 0;
  size_t tag_end = html.find(">", tag_start);
  if (tag_end == std::string::npos)
    return 0;
  return tag_end + 1;
}

void UILayoutTest::RunLayoutTest(const std::string& test_case_file_name,
                                 int port) {
  base::Time start = base::Time::Now();
  SCOPED_TRACE(test_case_file_name.c_str());

  ASSERT_TRUE(!layout_test_controller_.empty());

  // Creates a new cookie name. We will have to use a new cookie because
  // this function could be called multiple times.
  std::string status_cookie(kTestCompleteCookie);
  status_cookie += base::IntToString(test_count_);
  test_count_++;

  // Reads the layout test HTML file.
  FilePath test_file_path(layout_test_dir_);
  test_file_path = test_file_path.AppendASCII(test_case_file_name);
  std::string test_html;
  ASSERT_TRUE(file_util::ReadFileToString(test_file_path, &test_html));

  // Injects the layout test controller into the test HTML.
  size_t insertion_position = FindInsertPosition(test_html);
  test_html.insert(insertion_position, layout_test_controller_);
  ReplaceFirstSubstringAfterOffset(
      &test_html, insertion_position, "%COOKIE%", status_cookie.c_str());

  // Creates the new layout test HTML file.
  FilePath new_test_file_path(new_layout_test_dir_);
  new_test_file_path = new_test_file_path.AppendASCII(test_case_file_name);
  ASSERT_TRUE(file_util::WriteFile(new_test_file_path,
                                   &test_html.at(0),
                                   static_cast<int>(test_html.size())));

  scoped_ptr<GURL> new_test_url;
  if (port != kNoHttpPort)
    new_test_url.reset(new GURL(
        StringPrintf("http://localhost:%d/", port) +
        WideToUTF8(test_case_dir_.ToWStringHack()) +
        "/" +
        test_case_file_name));
  else
    new_test_url.reset(new GURL(net::FilePathToFileURL(new_test_file_path)));

  // Runs the new layout test.
  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());
  ASSERT_TRUE(tab->NavigateToURL(*new_test_url.get()));
  std::string escaped_value =
      WaitUntilCookieNonEmpty(tab.get(), *new_test_url.get(),
          status_cookie.c_str(), TestTimeouts::action_max_timeout_ms());

  // Unescapes and normalizes the actual result.
  std::string value = UnescapeURLComponent(escaped_value,
      UnescapeRule::NORMAL | UnescapeRule::SPACES |
          UnescapeRule::URL_SPECIAL_CHARS | UnescapeRule::CONTROL_CHARS);
  value += "\n";
  ReplaceSubstringsAfterOffset(&value, 0, "\r", "");

  // Reads the expected result. First try to read from rebase directory.
  // If failed, read from original directory.
  std::string expected_result_value;
  if (!ReadExpectedResult(rebase_result_dir_,
                          test_case_file_name,
                          &expected_result_value) &&
      !ReadExpectedResult(rebase_result_chromium_dir_,
                          test_case_file_name,
                          &expected_result_value)) {
    if (rebase_result_win_dir_.empty() ||
        !ReadExpectedResult(rebase_result_win_dir_,
                            test_case_file_name,
                            &expected_result_value))
      ReadExpectedResult(layout_test_dir_,
                         test_case_file_name,
                         &expected_result_value);
  }
  ASSERT_TRUE(!expected_result_value.empty());

  // Normalizes the expected result.
  ReplaceSubstringsAfterOffset(&expected_result_value, 0, "\r", "");

  // Compares the results.
  EXPECT_STREQ(expected_result_value.c_str(), value.c_str());

  VLOG(1) << "Test " << test_case_file_name
          << " took " << (base::Time::Now() - start).InMilliseconds() << "ms";
}

bool UILayoutTest::ReadExpectedResult(const FilePath& result_dir_path,
                                      const std::string test_case_file_name,
                                      std::string* expected_result_value) {
  FilePath expected_result_path(result_dir_path);
  expected_result_path = expected_result_path.AppendASCII(test_case_file_name);
  expected_result_path = expected_result_path.InsertBeforeExtension(
      FILE_PATH_LITERAL("-expected"));
  expected_result_path =
      expected_result_path.ReplaceExtension(FILE_PATH_LITERAL("txt"));
  return file_util::ReadFileToString(expected_result_path,
                                     expected_result_value);
}
<commit_msg>wstring: text case dirs are always ASCII<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/ui/ui_layout_test.h"

#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/test/test_file_util.h"
#include "base/test/test_timeouts.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/automation/tab_proxy.h"
#include "net/base/escape.h"
#include "net/base/net_util.h"

#if defined(OS_WIN)
static const char kPlatformName[] = "chromium-win";
#elif defined(OS_MACOSX)
static const char kPlatformName[] = "chromium-mac";
#elif defined(OS_LINUX)
static const char kPlatformName[] = "chromium-linux";
#else
#error No known OS defined
#endif

static const char kTestCompleteCookie[] = "status";

UILayoutTest::UILayoutTest()
    : initialized_for_layout_test_(false),
      test_count_(0) {
}

UILayoutTest::~UILayoutTest() {
  if (!temp_test_dir_.empty()) {
    // The deletion might fail because HTTP server process might not been
    // completely shut down yet and is still holding certain handle to it.
    // To work around this problem, we try to repeat the deletion several
    // times.
    EXPECT_TRUE(file_util::DieFileDie(temp_test_dir_, true));
  }
}

void UILayoutTest::InitializeForLayoutTest(const FilePath& test_parent_dir,
                                           const FilePath& test_case_dir,
                                           int port) {
  FilePath src_dir;
  PathService::Get(base::DIR_SOURCE_ROOT, &src_dir);

  src_dir = src_dir.AppendASCII("chrome");
  src_dir = src_dir.AppendASCII("test");
  src_dir = src_dir.AppendASCII("data");
  src_dir = src_dir.AppendASCII("layout_tests");
  src_dir = src_dir.AppendASCII("LayoutTests");

  // Gets the file path to WebKit ui layout tests, that is,
  //   chrome/test/data/ui_tests/LayoutTests/...
  // Note that we have to use our own copy of WebKit layout tests because our
  // build machines do not have WebKit layout tests added.
  layout_test_dir_ = src_dir.Append(test_parent_dir);
  layout_test_dir_ = layout_test_dir_.Append(test_case_dir);
  ASSERT_TRUE(file_util::DirectoryExists(layout_test_dir_));

  // Gets the file path to rebased expected result directory for the current
  // platform.
  //   chrome/test/data/layout_tests/LayoutTests/platform/chromium_***/...
  rebase_result_dir_ = src_dir.AppendASCII("platform");
  rebase_result_dir_ = rebase_result_dir_.AppendASCII(kPlatformName);
  rebase_result_dir_ = rebase_result_dir_.Append(test_parent_dir);
  rebase_result_dir_ = rebase_result_dir_.Append(test_case_dir);

  // Generic chromium expected results. Not OS-specific. For example,
  // v8-specific differences go here.
  // chrome/test/data/layout_tests/LayoutTests/platform/chromium/...
  rebase_result_chromium_dir_ = src_dir.AppendASCII("platform")
                                       .AppendASCII("chromium")
                                       .Append(test_parent_dir)
                                       .Append(test_case_dir);

  // Gets the file path to rebased expected result directory under the
  // win32 platform. This is used by other non-win32 platform to use the same
  // rebased expected results.
#if !defined(OS_WIN)
  rebase_result_win_dir_ = src_dir.AppendASCII("platform")
                                  .AppendASCII("chromium-win")
                                  .Append(test_parent_dir)
                                  .Append(test_case_dir);
#endif

  // Creates the temporary directory.
  ASSERT_TRUE(file_util::CreateNewTempDirectory(
      FILE_PATH_LITERAL("chrome_ui_layout_tests_"), &temp_test_dir_));

  // Creates the new layout test subdirectory under the temp directory.
  // Note that we have to mimic the same layout test directory structure,
  // like .../LayoutTests/fast/workers/.... Otherwise those layout tests
  // dealing with location property, like worker-location.html, could fail.
  new_layout_test_dir_ = temp_test_dir_;
  new_layout_test_dir_ = new_layout_test_dir_.AppendASCII("LayoutTests");
  new_layout_test_dir_ = new_layout_test_dir_.Append(test_parent_dir);
  if (port == kHttpPort) {
    new_http_root_dir_ = new_layout_test_dir_;
    test_case_dir_ = test_case_dir;
  }
  new_layout_test_dir_ = new_layout_test_dir_.Append(test_case_dir);
  ASSERT_TRUE(file_util::CreateDirectory(new_layout_test_dir_));

  // Copy the resource subdirectory if it exists.
  FilePath layout_test_resource_path(layout_test_dir_);
  layout_test_resource_path =
      layout_test_resource_path.AppendASCII("resources");
  FilePath new_layout_test_resource_path(new_layout_test_dir_);
  new_layout_test_resource_path =
      new_layout_test_resource_path.AppendASCII("resources");
  file_util::CopyDirectory(layout_test_resource_path,
                           new_layout_test_resource_path, true);

  // Copies the parent resource subdirectory. This is needed in order to run
  // http layout tests.
  if (port == kHttpPort) {
    FilePath parent_resource_path(layout_test_dir_.DirName());
    parent_resource_path = parent_resource_path.AppendASCII("resources");
    FilePath new_parent_resource_path(new_layout_test_dir_.DirName());
    new_parent_resource_path =
        new_parent_resource_path.AppendASCII("resources");
    ASSERT_TRUE(file_util::CopyDirectory(
        parent_resource_path, new_parent_resource_path, true));
  }

  // Reads the layout test controller simulation script.
  FilePath path;
  PathService::Get(chrome::DIR_TEST_DATA, &path);
  path = path.AppendASCII("layout_tests");
  path = path.AppendASCII("layout_test_controller.html");
  ASSERT_TRUE(file_util::ReadFileToString(path, &layout_test_controller_));
}

void UILayoutTest::AddResourceForLayoutTest(const FilePath& parent_dir,
                                            const FilePath& resource_name) {
  FilePath root_dir;
  PathService::Get(base::DIR_SOURCE_ROOT, &root_dir);

  FilePath source = root_dir.AppendASCII("chrome");
  source = source.AppendASCII("test");
  source = source.AppendASCII("data");
  source = source.AppendASCII("layout_tests");
  source = source.AppendASCII("LayoutTests");
  source = source.Append(parent_dir);
  source = source.Append(resource_name);

  ASSERT_TRUE(file_util::PathExists(source));

  FilePath dest_parent_dir = temp_test_dir_.
      AppendASCII("LayoutTests").Append(parent_dir);
  ASSERT_TRUE(file_util::CreateDirectory(dest_parent_dir));
  FilePath dest = dest_parent_dir.Append(resource_name);

  if (file_util::DirectoryExists(source)) {
    ASSERT_TRUE(file_util::CopyDirectory(source, dest, true));
  } else {
    ASSERT_TRUE(file_util::CopyFile(source, dest));
  }
}

static size_t FindInsertPosition(const std::string& html) {
  size_t tag_start = html.find("<html");
  if (tag_start == std::string::npos)
    return 0;
  size_t tag_end = html.find(">", tag_start);
  if (tag_end == std::string::npos)
    return 0;
  return tag_end + 1;
}

void UILayoutTest::RunLayoutTest(const std::string& test_case_file_name,
                                 int port) {
  base::Time start = base::Time::Now();
  SCOPED_TRACE(test_case_file_name.c_str());

  ASSERT_TRUE(!layout_test_controller_.empty());

  // Creates a new cookie name. We will have to use a new cookie because
  // this function could be called multiple times.
  std::string status_cookie(kTestCompleteCookie);
  status_cookie += base::IntToString(test_count_);
  test_count_++;

  // Reads the layout test HTML file.
  FilePath test_file_path(layout_test_dir_);
  test_file_path = test_file_path.AppendASCII(test_case_file_name);
  std::string test_html;
  ASSERT_TRUE(file_util::ReadFileToString(test_file_path, &test_html));

  // Injects the layout test controller into the test HTML.
  size_t insertion_position = FindInsertPosition(test_html);
  test_html.insert(insertion_position, layout_test_controller_);
  ReplaceFirstSubstringAfterOffset(
      &test_html, insertion_position, "%COOKIE%", status_cookie.c_str());

  // Creates the new layout test HTML file.
  FilePath new_test_file_path(new_layout_test_dir_);
  new_test_file_path = new_test_file_path.AppendASCII(test_case_file_name);
  ASSERT_TRUE(file_util::WriteFile(new_test_file_path,
                                   &test_html.at(0),
                                   static_cast<int>(test_html.size())));
  // We expect the test case dir to be ASCII.  It might be empty, so we
  // can't test whether MaybeAsASCII succeeded, but the tests will fail
  // loudly in that case anyway.
  std::string url_path = test_case_dir_.MaybeAsASCII();

  scoped_ptr<GURL> new_test_url;
  if (port != kNoHttpPort)
    new_test_url.reset(new GURL(
        StringPrintf("http://localhost:%d/", port) +
        url_path + "/" + test_case_file_name));
  else
    new_test_url.reset(new GURL(net::FilePathToFileURL(new_test_file_path)));

  // Runs the new layout test.
  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());
  ASSERT_TRUE(tab->NavigateToURL(*new_test_url.get()));
  std::string escaped_value =
      WaitUntilCookieNonEmpty(tab.get(), *new_test_url.get(),
          status_cookie.c_str(), TestTimeouts::action_max_timeout_ms());

  // Unescapes and normalizes the actual result.
  std::string value = UnescapeURLComponent(escaped_value,
      UnescapeRule::NORMAL | UnescapeRule::SPACES |
          UnescapeRule::URL_SPECIAL_CHARS | UnescapeRule::CONTROL_CHARS);
  value += "\n";
  ReplaceSubstringsAfterOffset(&value, 0, "\r", "");

  // Reads the expected result. First try to read from rebase directory.
  // If failed, read from original directory.
  std::string expected_result_value;
  if (!ReadExpectedResult(rebase_result_dir_,
                          test_case_file_name,
                          &expected_result_value) &&
      !ReadExpectedResult(rebase_result_chromium_dir_,
                          test_case_file_name,
                          &expected_result_value)) {
    if (rebase_result_win_dir_.empty() ||
        !ReadExpectedResult(rebase_result_win_dir_,
                            test_case_file_name,
                            &expected_result_value))
      ReadExpectedResult(layout_test_dir_,
                         test_case_file_name,
                         &expected_result_value);
  }
  ASSERT_TRUE(!expected_result_value.empty());

  // Normalizes the expected result.
  ReplaceSubstringsAfterOffset(&expected_result_value, 0, "\r", "");

  // Compares the results.
  EXPECT_STREQ(expected_result_value.c_str(), value.c_str());

  VLOG(1) << "Test " << test_case_file_name
          << " took " << (base::Time::Now() - start).InMilliseconds() << "ms";
}

bool UILayoutTest::ReadExpectedResult(const FilePath& result_dir_path,
                                      const std::string test_case_file_name,
                                      std::string* expected_result_value) {
  FilePath expected_result_path(result_dir_path);
  expected_result_path = expected_result_path.AppendASCII(test_case_file_name);
  expected_result_path = expected_result_path.InsertBeforeExtension(
      FILE_PATH_LITERAL("-expected"));
  expected_result_path =
      expected_result_path.ReplaceExtension(FILE_PATH_LITERAL("txt"));
  return file_util::ReadFileToString(expected_result_path,
                                     expected_result_value);
}
<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2016 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */
#include "runtimes/libjoynr-runtime/LibJoynrRuntime.h"

#include <cassert>
#include <vector>

#include "joynr/Dispatcher.h"
#include "joynr/InProcessDispatcher.h"
#include "joynr/system/RoutingTypes/CommonApiDbusAddress.h"
#include "joynr/PublicationManager.h"
#include "joynr/SubscriptionManager.h"
#include "joynr/InProcessPublicationSender.h"
#include "joynr/JoynrMessageSender.h"
#include "joynr/MessageRouter.h"
#include "libjoynr/in-process/InProcessLibJoynrMessagingSkeleton.h"
#include "joynr/InProcessMessagingAddress.h"
#include "joynr/MessagingStubFactory.h"
#include "libjoynr/in-process/InProcessMessagingStubFactory.h"
#include "joynr/system/DiscoveryProxy.h"
#include "joynr/TypeUtil.h"
#include "joynr/Util.h"
#include "joynr/Settings.h"
#include "joynr/SingleThreadedIOService.h"

namespace joynr
{

LibJoynrRuntime::LibJoynrRuntime(Settings* settings)
        : JoynrRuntime(*settings),
          subscriptionManager(nullptr),
          inProcessPublicationSender(nullptr),
          inProcessConnectorFactory(nullptr),
          joynrMessagingConnectorFactory(nullptr),
          joynrMessagingSendStub(nullptr),
          joynrMessageSender(nullptr),
          joynrDispatcher(nullptr),
          inProcessDispatcher(nullptr),
          settings(settings),
          libjoynrSettings(new LibjoynrSettings(*settings)),
          dispatcherMessagingSkeleton(nullptr),
          runtimeExecutor(nullptr)
{
    libjoynrSettings->printSettings();
}

LibJoynrRuntime::~LibJoynrRuntime()
{
    delete proxyFactory;
    delete inProcessDispatcher;
    delete joynrMessageSender;
    delete joynrDispatcher;
    delete libjoynrSettings;
    libjoynrSettings = nullptr;
    delete settings;
}

void LibJoynrRuntime::init(
        std::shared_ptr<IMiddlewareMessagingStubFactory> middlewareMessagingStubFactory,
        std::shared_ptr<const joynr::system::RoutingTypes::Address> libjoynrMessagingAddress,
        std::shared_ptr<const joynr::system::RoutingTypes::Address> ccMessagingAddress)
{
    // create messaging stub factory
    auto messagingStubFactory = std::make_shared<MessagingStubFactory>();
    middlewareMessagingStubFactory->registerOnMessagingStubClosedCallback([messagingStubFactory](
            const std::shared_ptr<const joynr::system::RoutingTypes::Address>& destinationAddress) {
        messagingStubFactory->remove(destinationAddress);
    });
    messagingStubFactory->registerStubFactory(middlewareMessagingStubFactory);
    messagingStubFactory->registerStubFactory(std::make_shared<InProcessMessagingStubFactory>());

    // create message router
    messageRouter = std::make_shared<MessageRouter>(std::move(messagingStubFactory),
                                                    libjoynrMessagingAddress,
                                                    singleThreadIOService->getIOService());

    messageRouter->loadRoutingTable(libjoynrSettings->getMessageRouterPersistenceFilename());
    startLibJoynrMessagingSkeleton(messageRouter);

    joynrMessageSender = new JoynrMessageSender(messageRouter);
    joynrDispatcher = new Dispatcher(joynrMessageSender, singleThreadIOService->getIOService());
    joynrMessageSender->registerDispatcher(joynrDispatcher);

    // create the inprocess skeleton for the dispatcher
    dispatcherMessagingSkeleton =
            std::make_shared<InProcessLibJoynrMessagingSkeleton>(joynrDispatcher);
    dispatcherAddress = std::make_shared<InProcessMessagingAddress>(dispatcherMessagingSkeleton);

    publicationManager = new PublicationManager(singleThreadIOService->getIOService());
    publicationManager->loadSavedAttributeSubscriptionRequestsMap(
            libjoynrSettings->getSubscriptionRequestPersistenceFilename());
    publicationManager->loadSavedBroadcastSubscriptionRequestsMap(
            libjoynrSettings->getBroadcastSubscriptionRequestPersistenceFilename());
    subscriptionManager = new SubscriptionManager(singleThreadIOService->getIOService());
    inProcessDispatcher = new InProcessDispatcher(singleThreadIOService->getIOService());

    inProcessPublicationSender = new InProcessPublicationSender(subscriptionManager);
    inProcessConnectorFactory = new InProcessConnectorFactory(
            subscriptionManager,
            publicationManager,
            inProcessPublicationSender,
            dynamic_cast<IRequestCallerDirectory*>(inProcessDispatcher));
    joynrMessagingConnectorFactory =
            new JoynrMessagingConnectorFactory(joynrMessageSender, subscriptionManager);

    auto connectorFactory = std::make_unique<ConnectorFactory>(
            inProcessConnectorFactory, joynrMessagingConnectorFactory);
    proxyFactory = new ProxyFactory(libjoynrMessagingAddress, std::move(connectorFactory), nullptr);

    // Set up the persistence file for storing provider participant ids
    std::string persistenceFilename = libjoynrSettings->getParticipantIdsPersistenceFilename();
    participantIdStorage = std::make_shared<ParticipantIdStorage>(persistenceFilename);

    // initialize the dispatchers
    std::vector<IDispatcher*> dispatcherList;
    dispatcherList.push_back(inProcessDispatcher);
    dispatcherList.push_back(joynrDispatcher);

    joynrDispatcher->registerPublicationManager(publicationManager);
    joynrDispatcher->registerSubscriptionManager(subscriptionManager);

    discoveryProxy = std::make_unique<LocalDiscoveryAggregator>(systemServicesSettings);
    requestCallerDirectory = dynamic_cast<IRequestCallerDirectory*>(inProcessDispatcher);

    std::string systemServicesDomain = systemServicesSettings.getDomain();
    std::string routingProviderParticipantId =
            systemServicesSettings.getCcRoutingProviderParticipantId();

    DiscoveryQos routingProviderDiscoveryQos;
    routingProviderDiscoveryQos.setCacheMaxAgeMs(1000);
    routingProviderDiscoveryQos.setArbitrationStrategy(
            DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT);
    routingProviderDiscoveryQos.addCustomParameter(
            "fixedParticipantId", routingProviderParticipantId);
    routingProviderDiscoveryQos.setDiscoveryTimeoutMs(50);

    std::unique_ptr<ProxyBuilder<joynr::system::RoutingProxy>> routingProxyBuilder(
            createProxyBuilder<joynr::system::RoutingProxy>(systemServicesDomain));
    auto routingProxy = routingProxyBuilder->setMessagingQos(MessagingQos(10000))
                                ->setCached(false)
                                ->setDiscoveryQos(routingProviderDiscoveryQos)
                                ->build();
    messageRouter->setParentRouter(std::unique_ptr<system::RoutingProxy>(routingProxy),
                                   ccMessagingAddress,
                                   routingProviderParticipantId);

    // setup discovery
    std::string discoveryProviderParticipantId =
            systemServicesSettings.getCcDiscoveryProviderParticipantId();
    DiscoveryQos discoveryProviderDiscoveryQos;
    discoveryProviderDiscoveryQos.setCacheMaxAgeMs(1000);
    discoveryProviderDiscoveryQos.setArbitrationStrategy(
            DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT);
    discoveryProviderDiscoveryQos.addCustomParameter(
            "fixedParticipantId", discoveryProviderParticipantId);
    discoveryProviderDiscoveryQos.setDiscoveryTimeoutMs(1000);

    std::unique_ptr<ProxyBuilder<joynr::system::DiscoveryProxy>> discoveryProxyBuilder(
            createProxyBuilder<joynr::system::DiscoveryProxy>(systemServicesDomain));
    joynr::system::IDiscoverySync* proxy =
            discoveryProxyBuilder->setMessagingQos(MessagingQos(40000))
                    ->setCached(false)
                    ->setDiscoveryQos(discoveryProviderDiscoveryQos)
                    ->build();
    discoveryProxy->setDiscoveryProxy(std::unique_ptr<joynr::system::IDiscoverySync>(proxy));
    capabilitiesRegistrar = std::make_unique<CapabilitiesRegistrar>(
            dispatcherList,
            *discoveryProxy,
            participantIdStorage,
            dispatcherAddress,
            messageRouter,
            messagingSettings.getDiscoveryEntryExpiryIntervalMs());
}

void LibJoynrRuntime::unregisterProvider(const std::string& participantId)
{
    assert(capabilitiesRegistrar);
    capabilitiesRegistrar->remove(participantId);
}

void LibJoynrRuntime::setRuntimeExecutor(JoynrRuntimeExecutor* runtimeExecutor)
{
    this->runtimeExecutor = std::unique_ptr<JoynrRuntimeExecutor>(runtimeExecutor);
}

LibJoynrRuntime* LibJoynrRuntime::create(JoynrRuntimeExecutor* runtimeExecutor)
{
    LibJoynrRuntime* runtime = runtimeExecutor->getRuntime();
    runtime->setRuntimeExecutor(runtimeExecutor);
    return runtime;
}

} // namespace joynr
<commit_msg>[C++] Avoid duplicate delete of settings object<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2016 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */
#include "runtimes/libjoynr-runtime/LibJoynrRuntime.h"

#include <cassert>
#include <vector>

#include "joynr/Dispatcher.h"
#include "joynr/InProcessDispatcher.h"
#include "joynr/system/RoutingTypes/CommonApiDbusAddress.h"
#include "joynr/PublicationManager.h"
#include "joynr/SubscriptionManager.h"
#include "joynr/InProcessPublicationSender.h"
#include "joynr/JoynrMessageSender.h"
#include "joynr/MessageRouter.h"
#include "libjoynr/in-process/InProcessLibJoynrMessagingSkeleton.h"
#include "joynr/InProcessMessagingAddress.h"
#include "joynr/MessagingStubFactory.h"
#include "libjoynr/in-process/InProcessMessagingStubFactory.h"
#include "joynr/system/DiscoveryProxy.h"
#include "joynr/TypeUtil.h"
#include "joynr/Util.h"
#include "joynr/Settings.h"
#include "joynr/SingleThreadedIOService.h"

namespace joynr
{

LibJoynrRuntime::LibJoynrRuntime(Settings* settings)
        : JoynrRuntime(*settings),
          subscriptionManager(nullptr),
          inProcessPublicationSender(nullptr),
          inProcessConnectorFactory(nullptr),
          joynrMessagingConnectorFactory(nullptr),
          joynrMessagingSendStub(nullptr),
          joynrMessageSender(nullptr),
          joynrDispatcher(nullptr),
          inProcessDispatcher(nullptr),
          settings(settings),
          libjoynrSettings(new LibjoynrSettings(*settings)),
          dispatcherMessagingSkeleton(nullptr),
          runtimeExecutor(nullptr)
{
    libjoynrSettings->printSettings();
}

LibJoynrRuntime::~LibJoynrRuntime()
{
    delete proxyFactory;
    delete inProcessDispatcher;
    delete joynrMessageSender;
    delete joynrDispatcher;
    delete libjoynrSettings;
    libjoynrSettings = nullptr;
}

void LibJoynrRuntime::init(
        std::shared_ptr<IMiddlewareMessagingStubFactory> middlewareMessagingStubFactory,
        std::shared_ptr<const joynr::system::RoutingTypes::Address> libjoynrMessagingAddress,
        std::shared_ptr<const joynr::system::RoutingTypes::Address> ccMessagingAddress)
{
    // create messaging stub factory
    auto messagingStubFactory = std::make_shared<MessagingStubFactory>();
    middlewareMessagingStubFactory->registerOnMessagingStubClosedCallback([messagingStubFactory](
            const std::shared_ptr<const joynr::system::RoutingTypes::Address>& destinationAddress) {
        messagingStubFactory->remove(destinationAddress);
    });
    messagingStubFactory->registerStubFactory(middlewareMessagingStubFactory);
    messagingStubFactory->registerStubFactory(std::make_shared<InProcessMessagingStubFactory>());

    // create message router
    messageRouter = std::make_shared<MessageRouter>(std::move(messagingStubFactory),
                                                    libjoynrMessagingAddress,
                                                    singleThreadIOService->getIOService());

    messageRouter->loadRoutingTable(libjoynrSettings->getMessageRouterPersistenceFilename());
    startLibJoynrMessagingSkeleton(messageRouter);

    joynrMessageSender = new JoynrMessageSender(messageRouter);
    joynrDispatcher = new Dispatcher(joynrMessageSender, singleThreadIOService->getIOService());
    joynrMessageSender->registerDispatcher(joynrDispatcher);

    // create the inprocess skeleton for the dispatcher
    dispatcherMessagingSkeleton =
            std::make_shared<InProcessLibJoynrMessagingSkeleton>(joynrDispatcher);
    dispatcherAddress = std::make_shared<InProcessMessagingAddress>(dispatcherMessagingSkeleton);

    publicationManager = new PublicationManager(singleThreadIOService->getIOService());
    publicationManager->loadSavedAttributeSubscriptionRequestsMap(
            libjoynrSettings->getSubscriptionRequestPersistenceFilename());
    publicationManager->loadSavedBroadcastSubscriptionRequestsMap(
            libjoynrSettings->getBroadcastSubscriptionRequestPersistenceFilename());
    subscriptionManager = new SubscriptionManager(singleThreadIOService->getIOService());
    inProcessDispatcher = new InProcessDispatcher(singleThreadIOService->getIOService());

    inProcessPublicationSender = new InProcessPublicationSender(subscriptionManager);
    inProcessConnectorFactory = new InProcessConnectorFactory(
            subscriptionManager,
            publicationManager,
            inProcessPublicationSender,
            dynamic_cast<IRequestCallerDirectory*>(inProcessDispatcher));
    joynrMessagingConnectorFactory =
            new JoynrMessagingConnectorFactory(joynrMessageSender, subscriptionManager);

    auto connectorFactory = std::make_unique<ConnectorFactory>(
            inProcessConnectorFactory, joynrMessagingConnectorFactory);
    proxyFactory = new ProxyFactory(libjoynrMessagingAddress, std::move(connectorFactory), nullptr);

    // Set up the persistence file for storing provider participant ids
    std::string persistenceFilename = libjoynrSettings->getParticipantIdsPersistenceFilename();
    participantIdStorage = std::make_shared<ParticipantIdStorage>(persistenceFilename);

    // initialize the dispatchers
    std::vector<IDispatcher*> dispatcherList;
    dispatcherList.push_back(inProcessDispatcher);
    dispatcherList.push_back(joynrDispatcher);

    joynrDispatcher->registerPublicationManager(publicationManager);
    joynrDispatcher->registerSubscriptionManager(subscriptionManager);

    discoveryProxy = std::make_unique<LocalDiscoveryAggregator>(systemServicesSettings);
    requestCallerDirectory = dynamic_cast<IRequestCallerDirectory*>(inProcessDispatcher);

    std::string systemServicesDomain = systemServicesSettings.getDomain();
    std::string routingProviderParticipantId =
            systemServicesSettings.getCcRoutingProviderParticipantId();

    DiscoveryQos routingProviderDiscoveryQos;
    routingProviderDiscoveryQos.setCacheMaxAgeMs(1000);
    routingProviderDiscoveryQos.setArbitrationStrategy(
            DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT);
    routingProviderDiscoveryQos.addCustomParameter(
            "fixedParticipantId", routingProviderParticipantId);
    routingProviderDiscoveryQos.setDiscoveryTimeoutMs(50);

    std::unique_ptr<ProxyBuilder<joynr::system::RoutingProxy>> routingProxyBuilder(
            createProxyBuilder<joynr::system::RoutingProxy>(systemServicesDomain));
    auto routingProxy = routingProxyBuilder->setMessagingQos(MessagingQos(10000))
                                ->setCached(false)
                                ->setDiscoveryQos(routingProviderDiscoveryQos)
                                ->build();
    messageRouter->setParentRouter(std::unique_ptr<system::RoutingProxy>(routingProxy),
                                   ccMessagingAddress,
                                   routingProviderParticipantId);

    // setup discovery
    std::string discoveryProviderParticipantId =
            systemServicesSettings.getCcDiscoveryProviderParticipantId();
    DiscoveryQos discoveryProviderDiscoveryQos;
    discoveryProviderDiscoveryQos.setCacheMaxAgeMs(1000);
    discoveryProviderDiscoveryQos.setArbitrationStrategy(
            DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT);
    discoveryProviderDiscoveryQos.addCustomParameter(
            "fixedParticipantId", discoveryProviderParticipantId);
    discoveryProviderDiscoveryQos.setDiscoveryTimeoutMs(1000);

    std::unique_ptr<ProxyBuilder<joynr::system::DiscoveryProxy>> discoveryProxyBuilder(
            createProxyBuilder<joynr::system::DiscoveryProxy>(systemServicesDomain));
    joynr::system::IDiscoverySync* proxy =
            discoveryProxyBuilder->setMessagingQos(MessagingQos(40000))
                    ->setCached(false)
                    ->setDiscoveryQos(discoveryProviderDiscoveryQos)
                    ->build();
    discoveryProxy->setDiscoveryProxy(std::unique_ptr<joynr::system::IDiscoverySync>(proxy));
    capabilitiesRegistrar = std::make_unique<CapabilitiesRegistrar>(
            dispatcherList,
            *discoveryProxy,
            participantIdStorage,
            dispatcherAddress,
            messageRouter,
            messagingSettings.getDiscoveryEntryExpiryIntervalMs());
}

void LibJoynrRuntime::unregisterProvider(const std::string& participantId)
{
    assert(capabilitiesRegistrar);
    capabilitiesRegistrar->remove(participantId);
}

void LibJoynrRuntime::setRuntimeExecutor(JoynrRuntimeExecutor* runtimeExecutor)
{
    this->runtimeExecutor = std::unique_ptr<JoynrRuntimeExecutor>(runtimeExecutor);
}

LibJoynrRuntime* LibJoynrRuntime::create(JoynrRuntimeExecutor* runtimeExecutor)
{
    LibJoynrRuntime* runtime = runtimeExecutor->getRuntime();
    runtime->setRuntimeExecutor(runtimeExecutor);
    return runtime;
}

} // namespace joynr
<|endoftext|>


<commit_before>/*********************************************************************************
* Copyright (c) 2013 David D. Marshall <ddmarsha@calpoly.edu>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    David D. Marshall - initial code and implementation
********************************************************************************/

#ifndef piecewise_four_digit_creator_test_suite_hpp
#define piecewise_four_digit_creator_test_suite_hpp

#include "eli/code_eli.hpp"

#include "eli/constants/math.hpp"
#include "eli/mutil/fd/d1o2.hpp"
#include "eli/mutil/fd/d2o2.hpp"
#include "eli/geom/curve/piecewise.hpp"
#include "eli/geom/curve/piecewise_four_digit_creator.hpp"

#include <cmath>    // std::pow, std::exp
#include <cassert>  // assert()

#include <typeinfo> // typeid
#include <string>   // std::string
#include <sstream>  // std::stringstream
#include <iomanip>  // std::setw
#include <limits>   // std::numeric_limits

template<typename data__>
class piecewise_four_digit_creator_test_suite : public Test::Suite
{
  private:
    typedef eli::geom::curve::piecewise<eli::geom::curve::bezier, data__, 3> piecewise_curve_type;
    typedef typename piecewise_curve_type::curve_type curve_type;
    typedef typename piecewise_curve_type::point_type point_type;
    typedef typename piecewise_curve_type::data_type data_type;
    typedef typename piecewise_curve_type::index_type index_type;
    typedef typename piecewise_curve_type::tolerance_type tolerance_type;
    typedef eli::geom::curve::piecewise_four_digit_creator<data__, 3, tolerance_type> point_creator_type;

    tolerance_type tol;

  protected:
    void AddTests(const float &)
    {
      // add the tests
      TEST_ADD(piecewise_four_digit_creator_test_suite<float>::create_airfoil_test);
    }
    void AddTests(const double &)
    {
      // add the tests
      TEST_ADD(piecewise_four_digit_creator_test_suite<double>::create_airfoil_test);
    }
    void AddTests(const long double &)
    {
      // add the tests
      TEST_ADD(piecewise_four_digit_creator_test_suite<long double>::create_airfoil_test);
    }

  public:
    piecewise_four_digit_creator_test_suite() : tol()
    {
      AddTests(data__());
    }
    ~piecewise_four_digit_creator_test_suite()
    {
    }

  private:
    void octave_print(int figno, const piecewise_curve_type &pc) const
    {
      index_type i, pp, ns;
      data_type tmin, tmax;

      ns=pc.number_segments();
      pc.get_parameter_min(tmin);
      pc.get_parameter_max(tmax);

      std::cout << "figure(" << figno << ");" << std::endl;

      // get control points and print
      std::cout << "cp_x=[";
      for (pp=0; pp<ns; ++pp)
      {
        curve_type bez;
        pc.get(bez, pp);
        for (i=0; i<=bez.degree(); ++i)
        {
          std::cout << bez.get_control_point(i).x();
          if (i<bez.degree())
            std::cout << ", ";
          else if (pp<ns-1)
            std::cout << "; ";
        }
        std::cout << std::endl;
      }
      std::cout << "];" << std::endl;

      std::cout << "cp_y=[";
      for (pp=0; pp<ns; ++pp)
      {
        curve_type bez;
        pc.get(bez, pp);
        for (i=0; i<=bez.degree(); ++i)
        {
          std::cout << bez.get_control_point(i).y();
          if (i<bez.degree())
            std::cout << ", ";
          else if (pp<ns-1)
            std::cout << "; ";
        }
        std::cout << std::endl;
      }
      std::cout << "];" << std::endl;

      std::cout << "cp_z=[";
      for (pp=0; pp<ns; ++pp)
      {
        curve_type bez;
        pc.get(bez, pp);
        for (i=0; i<=bez.degree(); ++i)
        {
          std::cout << bez.get_control_point(i).z();
          if (i<bez.degree())
            std::cout << ", ";
          else if (pp<ns-1)
            std::cout << "; ";
        }
        std::cout << std::endl;
      }
      std::cout << "];" << std::endl;

      // initialize the t parameters
      std::vector<data__> t(129);
      for (i=0; i<static_cast<index_type>(t.size()); ++i)
      {
        t[i]=tmin+(tmax-tmin)*static_cast<data__>(i)/(t.size()-1);
      }

      // set the surface points
      std::cout << "surf_x=[";
      for (i=0; i<static_cast<index_type>(t.size()); ++i)
      {
        std::cout << pc.f(t[i]).x();
        if (i<static_cast<index_type>(t.size()-1))
          std::cout << ", ";
      }
      std::cout << "];" << std::endl;

      std::cout << "surf_y=[";
      for (i=0; i<static_cast<index_type>(t.size()); ++i)
      {
        std::cout << pc.f(t[i]).y();
        if (i<static_cast<index_type>(t.size()-1))
          std::cout << ", ";
      }
      std::cout << "];" << std::endl;

      std::cout << "surf_z=[";
      for (i=0; i<static_cast<index_type>(t.size()); ++i)
      {
        std::cout << pc.f(t[i]).z();
        if (i<static_cast<index_type>(t.size()-1))
          std::cout << ", ";
      }
      std::cout << "];" << std::endl;

      std::cout << "setenv('GNUTERM', 'x11');" << std::endl;
      std::cout << "plot3(surf_x, surf_y, surf_z, '-k');" << std::endl;
      std::cout << "hold on;" << std::endl;
      std::cout << "plot3(cp_x', cp_y', cp_z', '-ok', 'MarkerFaceColor', [0 0 0]);" << std::endl;
      std::cout << "hold off;" << std::endl;
    }

    void create_airfoil_test()
    {
#if 0
      airfoil_type af;

      data_type th, cam, cam_loc;
      bool rtn;

      // set airfoil thickness
      th=24;
      rtn=af.set_thickness(th);
      TEST_ASSERT(rtn);
      TEST_ASSERT(af.get_thickness()==th);

      // set airfoil camber
      cam=2;
      cam_loc=3;
      rtn=af.set_camber(cam, cam_loc);
      TEST_ASSERT(rtn);
      TEST_ASSERT(af.get_maximum_camber()==cam);
      TEST_ASSERT(af.get_maximum_camber_location()==cam_loc);

      // test the name
      std::string name, name_ref;

      name_ref="NACA "+std::to_string((int)round(cam))+std::to_string((int)round(cam_loc))+std::to_string((int)round(th));
      name=af.get_name();
      TEST_ASSERT(name==name_ref);
#endif
    }
};

#endif

<commit_msg>Make 4-digit airfoil test plots in 2D<commit_after>/*********************************************************************************
* Copyright (c) 2013 David D. Marshall <ddmarsha@calpoly.edu>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    David D. Marshall - initial code and implementation
********************************************************************************/

#ifndef piecewise_four_digit_creator_test_suite_hpp
#define piecewise_four_digit_creator_test_suite_hpp

#include "eli/code_eli.hpp"

#include "eli/constants/math.hpp"
#include "eli/mutil/fd/d1o2.hpp"
#include "eli/mutil/fd/d2o2.hpp"
#include "eli/geom/curve/piecewise.hpp"
#include "eli/geom/curve/piecewise_four_digit_creator.hpp"

#include <cmath>    // std::pow, std::exp
#include <cassert>  // assert()

#include <typeinfo> // typeid
#include <string>   // std::string
#include <sstream>  // std::stringstream
#include <iomanip>  // std::setw
#include <limits>   // std::numeric_limits

template<typename data__>
class piecewise_four_digit_creator_test_suite : public Test::Suite
{
  private:
    typedef eli::geom::curve::piecewise<eli::geom::curve::bezier, data__, 3> piecewise_curve_type;
    typedef typename piecewise_curve_type::curve_type curve_type;
    typedef typename piecewise_curve_type::point_type point_type;
    typedef typename piecewise_curve_type::data_type data_type;
    typedef typename piecewise_curve_type::index_type index_type;
    typedef typename piecewise_curve_type::tolerance_type tolerance_type;
    typedef eli::geom::curve::piecewise_four_digit_creator<data__, 3, tolerance_type> point_creator_type;

    tolerance_type tol;

  protected:
    void AddTests(const float &)
    {
      // add the tests
      TEST_ADD(piecewise_four_digit_creator_test_suite<float>::create_airfoil_test);
    }
    void AddTests(const double &)
    {
      // add the tests
      TEST_ADD(piecewise_four_digit_creator_test_suite<double>::create_airfoil_test);
    }
    void AddTests(const long double &)
    {
      // add the tests
      TEST_ADD(piecewise_four_digit_creator_test_suite<long double>::create_airfoil_test);
    }

  public:
    piecewise_four_digit_creator_test_suite() : tol()
    {
      AddTests(data__());
    }
    ~piecewise_four_digit_creator_test_suite()
    {
    }

  private:
    void octave_print(int figno, const piecewise_curve_type &pc) const
    {
      index_type i, pp, ns;
      data_type tmin, tmax;

      ns=pc.number_segments();
      pc.get_parameter_min(tmin);
      pc.get_parameter_max(tmax);

      std::cout << "figure(" << figno << ");" << std::endl;

      // get control points and print
      std::cout << "cp_x=[";
      for (pp=0; pp<ns; ++pp)
      {
        curve_type bez;
        pc.get(bez, pp);
        for (i=0; i<=bez.degree(); ++i)
        {
          std::cout << bez.get_control_point(i).x();
          if (i<bez.degree())
            std::cout << ", ";
          else if (pp<ns-1)
            std::cout << "; ";
        }
        std::cout << std::endl;
      }
      std::cout << "];" << std::endl;

      std::cout << "cp_y=[";
      for (pp=0; pp<ns; ++pp)
      {
        curve_type bez;
        pc.get(bez, pp);
        for (i=0; i<=bez.degree(); ++i)
        {
          std::cout << bez.get_control_point(i).y();
          if (i<bez.degree())
            std::cout << ", ";
          else if (pp<ns-1)
            std::cout << "; ";
        }
        std::cout << std::endl;
      }
      std::cout << "];" << std::endl;

      std::cout << "cp_z=[";
      for (pp=0; pp<ns; ++pp)
      {
        curve_type bez;
        pc.get(bez, pp);
        for (i=0; i<=bez.degree(); ++i)
        {
          std::cout << bez.get_control_point(i).z();
          if (i<bez.degree())
            std::cout << ", ";
          else if (pp<ns-1)
            std::cout << "; ";
        }
        std::cout << std::endl;
      }
      std::cout << "];" << std::endl;

      // initialize the t parameters
      std::vector<data__> t(129);
      for (i=0; i<static_cast<index_type>(t.size()); ++i)
      {
        t[i]=tmin+(tmax-tmin)*static_cast<data__>(i)/(t.size()-1);
      }

      // set the surface points
      std::cout << "surf_x=[";
      for (i=0; i<static_cast<index_type>(t.size()); ++i)
      {
        std::cout << pc.f(t[i]).x();
        if (i<static_cast<index_type>(t.size()-1))
          std::cout << ", ";
      }
      std::cout << "];" << std::endl;

      std::cout << "surf_y=[";
      for (i=0; i<static_cast<index_type>(t.size()); ++i)
      {
        std::cout << pc.f(t[i]).y();
        if (i<static_cast<index_type>(t.size()-1))
          std::cout << ", ";
      }
      std::cout << "];" << std::endl;

      std::cout << "surf_z=[";
      for (i=0; i<static_cast<index_type>(t.size()); ++i)
      {
        std::cout << pc.f(t[i]).z();
        if (i<static_cast<index_type>(t.size()-1))
          std::cout << ", ";
      }
      std::cout << "];" << std::endl;

      std::cout << "setenv('GNUTERM', 'x11');" << std::endl;
      std::cout << "plot(surf_x, surf_y, '-k');" << std::endl;
      std::cout << "hold on;" << std::endl;
      std::cout << "plot(cp_x', cp_y', '-ok', 'MarkerFaceColor', [0 0 0]);" << std::endl;
      std::cout << "hold off;" << std::endl;
      std::cout << "axis equal;" << std::endl;
    }

    void create_airfoil_test()
    {
#if 0
      airfoil_type af;

      data_type th, cam, cam_loc;
      bool rtn;

      // set airfoil thickness
      th=24;
      rtn=af.set_thickness(th);
      TEST_ASSERT(rtn);
      TEST_ASSERT(af.get_thickness()==th);

      // set airfoil camber
      cam=2;
      cam_loc=3;
      rtn=af.set_camber(cam, cam_loc);
      TEST_ASSERT(rtn);
      TEST_ASSERT(af.get_maximum_camber()==cam);
      TEST_ASSERT(af.get_maximum_camber_location()==cam_loc);

      // test the name
      std::string name, name_ref;

      name_ref="NACA "+std::to_string((int)round(cam))+std::to_string((int)round(cam_loc))+std::to_string((int)round(th));
      name=af.get_name();
      TEST_ASSERT(name==name_ref);
#endif
    }
};

#endif

<|endoftext|>


<commit_before>#include <botan/botan.h>
#include <botan/tls_server.h>

#include <botan/rsa.h>
#include <botan/dsa.h>
#include <botan/x509self.h>
#include <botan/secqueue.h>

#include "socket.h"

using namespace Botan;

#include <stdio.h>
#include <string>
#include <iostream>
#include <memory>

class Blocking_TLS_Server
   {
   public:
      Blocking_TLS_Server(std::tr1::function<void (const byte[], size_t)> output_fn,
                          std::tr1::function<size_t (byte[], size_t)> input_fn,
                          TLS_Session_Manager& sessions,
                          TLS_Policy& policy,
                          RandomNumberGenerator& rng,
                          const X509_Certificate& cert,
                          const Private_Key& key) :
         input_fn(input_fn),
         server(
            output_fn,
            std::tr1::bind(&Blocking_TLS_Server::reader_fn, std::tr1::ref(*this), _1, _2, _3),
            sessions,
            policy,
            rng,
            cert,
            key),
         exit(false)
         {
         read_loop();
         }

      size_t read(byte buf[], size_t buf_len)
         {
         size_t got = read_queue.read(buf, buf_len);

         while(!exit && !got)
            {
            read_loop(5); // header size
            got = read_queue.read(buf, buf_len);
            }

         return got;
         }

      void write(const byte buf[], size_t buf_len)
         {
         server.queue_for_sending(buf, buf_len);
         }

      void close() { server.close(); }

      bool is_active() const { return server.is_active(); }

      TLS_Server& underlying() { return server; }
   private:
      void read_loop(size_t init_desired = 0)
         {
         size_t desired = init_desired;

         byte buf[4096];
         while(!exit && (!server.is_active() || desired))
            {
            const size_t asking = std::max(sizeof(buf), std::min(desired, static_cast<size_t>(1)));

            const size_t socket_got = input_fn(&buf[0], asking);

            if(socket_got == 0) // eof?
               {
               close();
               exit = true;
               }

            desired = server.received_data(&buf[0], socket_got);
            }
         }

      void reader_fn(const byte buf[], size_t buf_len, u16bit alert_code)
         {
         if(buf_len == 0 && alert_code != NULL_ALERT)
            {
            printf("Alert: %d, quitting\n", alert_code);
            exit = true;
            }

         printf("Got %d bytes: ", (int)buf_len);
         for(size_t i = 0; i != buf_len; ++i)
            {
            if(isprint(buf[i]))
               printf("%c", buf[i]);
            else
               printf("0x%02X", buf[i]);
            }
         printf("\n");

         read_queue.write(buf, buf_len);
         }

      std::tr1::function<size_t (byte[], size_t)> input_fn;
      TLS_Server server;
      SecureQueue read_queue;
      bool exit;
   };

class Server_TLS_Policy : public TLS_Policy
   {
   public:
      bool require_client_auth() const { return true; }

      bool check_cert(const std::vector<X509_Certificate>& certs) const
         {
         for(size_t i = 0; i != certs.size(); ++i)
            {
            std::cout << certs[i].to_string();
            }

         std::cout << "Warning: not checking cert signatures\n";

         return true;
         }
   };

int main(int argc, char* argv[])
   {
   int port = 4433;

   if(argc == 2)
      port = to_u32bit(argv[1]);

   try
      {
      LibraryInitializer botan_init;
      //SocketInitializer socket_init;

      AutoSeeded_RNG rng;

      //RSA_PrivateKey key(rng, 1024);
      DSA_PrivateKey key(rng, DL_Group("dsa/jce/1024"));

      X509_Cert_Options options(
         "localhost/US/Syn Ack Labs/Mathematical Munitions Dept");

      X509_Certificate cert =
         X509::create_self_signed_cert(options, key, "SHA-1", rng);

      Server_Socket listener(port);

      Server_TLS_Policy policy;

      TLS_Session_Manager_In_Memory sessions;

      while(true)
         {
         try {
            printf("Listening for new connection on port %d\n", port);

            Socket* sock = listener.accept();

            printf("Got new connection\n");

            Blocking_TLS_Server tls(
               std::tr1::bind(&Socket::write, std::tr1::ref(sock), _1, _2),
               std::tr1::bind(&Socket::read, std::tr1::ref(sock), _1, _2, true),
               sessions,
               policy,
               rng,
               cert,
               key);

            const char* msg = "Welcome to the best echo server evar\n";
            tls.write((const Botan::byte*)msg, strlen(msg));

            std::string line;

            while(tls.is_active())
               {
               byte b;
               size_t got = tls.read(&b, 1);

               if(got == 0)
                  break;

               line += (char)b;
               if(b == '\n')
                  {
                  tls.write(reinterpret_cast<const byte*>(line.data()), line.size());

                  if(line == "quit\n")
                     {
                     tls.close();
                     break;
                     }

                  line.clear();
                  }
               }
            }
         catch(std::exception& e) { printf("Connection problem: %s\n", e.what()); }
         }
   }
   catch(std::exception& e)
      {
      printf("%s\n", e.what());
      return 1;
      }
   return 0;
   }
<commit_msg>Just print printable<commit_after>#include <botan/botan.h>
#include <botan/tls_server.h>

#include <botan/rsa.h>
#include <botan/dsa.h>
#include <botan/x509self.h>
#include <botan/secqueue.h>

#include "socket.h"

using namespace Botan;

#include <stdio.h>
#include <string>
#include <iostream>
#include <memory>

class Blocking_TLS_Server
   {
   public:
      Blocking_TLS_Server(std::tr1::function<void (const byte[], size_t)> output_fn,
                          std::tr1::function<size_t (byte[], size_t)> input_fn,
                          TLS_Session_Manager& sessions,
                          TLS_Policy& policy,
                          RandomNumberGenerator& rng,
                          const X509_Certificate& cert,
                          const Private_Key& key) :
         input_fn(input_fn),
         server(
            output_fn,
            std::tr1::bind(&Blocking_TLS_Server::reader_fn, std::tr1::ref(*this), _1, _2, _3),
            sessions,
            policy,
            rng,
            cert,
            key),
         exit(false)
         {
         read_loop();
         }

      size_t read(byte buf[], size_t buf_len)
         {
         size_t got = read_queue.read(buf, buf_len);

         while(!exit && !got)
            {
            read_loop(5); // header size
            got = read_queue.read(buf, buf_len);
            }

         return got;
         }

      void write(const byte buf[], size_t buf_len)
         {
         server.queue_for_sending(buf, buf_len);
         }

      void close() { server.close(); }

      bool is_active() const { return server.is_active(); }

      TLS_Server& underlying() { return server; }
   private:
      void read_loop(size_t init_desired = 0)
         {
         size_t desired = init_desired;

         byte buf[4096];
         while(!exit && (!server.is_active() || desired))
            {
            const size_t asking = std::max(sizeof(buf), std::min(desired, static_cast<size_t>(1)));

            const size_t socket_got = input_fn(&buf[0], asking);

            if(socket_got == 0) // eof?
               {
               close();
               exit = true;
               }

            desired = server.received_data(&buf[0], socket_got);
            }
         }

      void reader_fn(const byte buf[], size_t buf_len, u16bit alert_code)
         {
         if(buf_len == 0 && alert_code != NULL_ALERT)
            {
            printf("Alert: %d, quitting\n", alert_code);
            exit = true;
            }

         printf("Got %d bytes: ", (int)buf_len);
         for(size_t i = 0; i != buf_len; ++i)
            {
            if(isprint(buf[i]))
               printf("%c", buf[i]);
            }
         printf("\n");

         read_queue.write(buf, buf_len);
         }

      std::tr1::function<size_t (byte[], size_t)> input_fn;
      TLS_Server server;
      SecureQueue read_queue;
      bool exit;
   };

class Server_TLS_Policy : public TLS_Policy
   {
   public:
      bool require_client_auth() const { return true; }

      bool check_cert(const std::vector<X509_Certificate>& certs) const
         {
         for(size_t i = 0; i != certs.size(); ++i)
            {
            std::cout << certs[i].to_string();
            }

         std::cout << "Warning: not checking cert signatures\n";

         return true;
         }
   };

int main(int argc, char* argv[])
   {
   int port = 4433;

   if(argc == 2)
      port = to_u32bit(argv[1]);

   try
      {
      LibraryInitializer botan_init;
      //SocketInitializer socket_init;

      AutoSeeded_RNG rng;

      //RSA_PrivateKey key(rng, 1024);
      DSA_PrivateKey key(rng, DL_Group("dsa/jce/1024"));

      X509_Cert_Options options(
         "localhost/US/Syn Ack Labs/Mathematical Munitions Dept");

      X509_Certificate cert =
         X509::create_self_signed_cert(options, key, "SHA-1", rng);

      Server_Socket listener(port);

      Server_TLS_Policy policy;

      TLS_Session_Manager_In_Memory sessions;

      while(true)
         {
         try {
            printf("Listening for new connection on port %d\n", port);

            Socket* sock = listener.accept();

            printf("Got new connection\n");

            Blocking_TLS_Server tls(
               std::tr1::bind(&Socket::write, std::tr1::ref(sock), _1, _2),
               std::tr1::bind(&Socket::read, std::tr1::ref(sock), _1, _2, true),
               sessions,
               policy,
               rng,
               cert,
               key);

            const char* msg = "Welcome to the best echo server evar\n";
            tls.write((const Botan::byte*)msg, strlen(msg));

            std::string line;

            while(tls.is_active())
               {
               byte b;
               size_t got = tls.read(&b, 1);

               if(got == 0)
                  break;

               line += (char)b;
               if(b == '\n')
                  {
                  tls.write(reinterpret_cast<const byte*>(line.data()), line.size());

                  if(line == "quit\n")
                     {
                     tls.close();
                     break;
                     }

                  line.clear();
                  }
               }
            }
         catch(std::exception& e) { printf("Connection problem: %s\n", e.what()); }
         }
   }
   catch(std::exception& e)
      {
      printf("%s\n", e.what());
      return 1;
      }
   return 0;
   }
<|endoftext|>


<commit_before>#include "command.h"
#include "events.h"
#include <iostream>

void Command::run(Bot *bot, IRCMessageEvent *ev)
{
	try
	{
		auto t = Command::parse(bot, ev);

		CommandInfo *i = std::get<0>(t);
		std::vector<CommandBase*> &v = std::get<1>(t);

		CommandInfo* curr = i;

		for(auto cmd: v)
		{
			cmd->run(bot, curr);
			if(curr != NULL)
			{
				curr = curr-> next;
			}
		}

		while(curr->in.size() != 0)
		{
			// todo: clean
			bot->conn->send_privmsg(ev->target, curr->pop()->to_string());
		}

		delete i;
	}
	catch(CommandNotFoundException e)
	{
		bot->conn->send_privmsg(ev->target, "Command '" + e.command + "' not found!");
	}
	catch(PermissionDeniedException e)
	{
		bot->conn->send_privmsg(ev->target, "Permission denied for '" + e.command + "'!");
	}
	catch(CommandErrorException e)
	{
		bot->conn->send_privmsg(ev->target, "Command '" + e.command + "' threw error '" + e.err + "'!");
	}
}

bool check_permissions(Bot *bot, User *u, std::string target, std::string command);

std::tuple<CommandInfo*, std::vector<CommandBase*>> Command::parse(Bot *bot, IRCMessageEvent *ev)
{
	CommandInfo *info = new CommandInfo();
	CommandInfo *curr = info;

	std::vector<CommandBase*> v;

	std::string &s = ev->message;

	const int type_str = 0;
	const int type_delim = 1;

	std::vector<std::pair<int, std::string>> tokens;

	std::string tmp;

	size_t i = 0;

	bool quote = false;
	bool ignore = false;

	for(; i < s.length() ; i++)
	{
		char c = s[i];

		switch(c)
		{
			case '\"':
				if(quote)
				{
					tokens.push_back(std::make_pair(type_str, tmp));
					tmp.clear();
					ignore = true;
					quote = false;
				}
				else
				{
					quote = true;
				}
			break;

			case '|':
				tokens.push_back(std::make_pair(type_delim, ""));
				tmp.clear();
				ignore = true;
			break;

			case ' ':
				if(!ignore)
				{
					if(!quote && tmp != "")
					{
						tokens.push_back(std::make_pair(type_str, tmp));
						tmp.clear();
						ignore = true;
					}
					else
					{
						tmp += c;
					}
				}
			break;

			default:
				if(ignore) { ignore = false; }
				tmp += c;
			break;
		}
	}

	if(tmp != "")
	{
		tokens.push_back(std::make_pair(type_str, tmp));
	}

	bool cmd = true;

	for(auto a: tokens)
	{
		if(a.first == type_str)
		{
			if(cmd)
			{
				cmd = false;

				if(!check_permissions(bot, ev->sender, ev->target, a.second))
				{
					throw PermissionDeniedException(a.second);
				}

				CommandBase *b = bot->get_command(a.second);
				if(b == NULL)
				{
					delete info;
					throw CommandNotFoundException(a.second);
				}
				v.push_back(b);
			}
			else
			{
				curr->in.push_back(new StringData(a.second));
			}
		}
		else if(a.first == type_delim)
		{
			cmd = true;

			curr->sender = ev->sender;
			curr->target = ev->target;
			curr->cmd = v.back();

			curr->next = new CommandInfo();
			curr = curr->next;
		}
	}

	curr->cmd = v.back();
	curr->sender = ev->sender;
	curr->target = ev->target;

	curr->next = new CommandInfo();
	curr->next->sender = ev->sender;
	curr->next->target = ev->target;

	return std::make_tuple(info, v);
}

bool check_permissions(Bot *bot, User *u, std::string target, std::string command)
{
	if(!u->synced || u->account == "*")
	{
		return false;
	}

	std::shared_ptr<ConfigNode> v = bot->config->get("permissions." + command);

	if(v->type() == NodeType::List)
	{
		for(auto a : v->as_list())
		{
			std::string b = a;
			if(b == u->account)
			{
				return true;
			}
			else if(b.substr(0, 6) == "group/")
			{
				b = b.substr(6);

				if(b == "special/all")
				{
					return true;
				}
				else if(b == "special/none")
				{
					return false;
				}
				else if(b == "special/ops")
				{
					if(target[0] == '#')
					{
						Channel &c = bot->conn->get_channel(target);
						return c.users[u->nick].modes['o'];
					}
					else
					{
						return false;
					}
				}
				else if(b == "special/voice")
				{
					if(target[0] == '#')
					{
						Channel &c = bot->conn->get_channel(target);
						return c.users[u->nick].modes['v'];
					}
					else
					{
						return false;
					}
				}

				std::shared_ptr<ConfigNode> v2 = bot->config->get("groups." + b);
				if(v2->type() == NodeType::List)
				{
					for(auto c : v2->as_list())
					{
						if(c == u->account)
						{
							return true;
						}
					}
				}
			}
		}
	}

	return false;
}

CommandBase *Command::get_ptr(std::string n)
{
	std::cout << "Trying to get command " << n << std::endl;
	return NULL;
}<commit_msg>check perms after existence of commands<commit_after>#include "command.h"
#include "events.h"
#include <iostream>

void Command::run(Bot *bot, IRCMessageEvent *ev)
{
	try
	{
		auto t = Command::parse(bot, ev);

		CommandInfo *i = std::get<0>(t);
		std::vector<CommandBase*> &v = std::get<1>(t);

		CommandInfo* curr = i;

		for(auto cmd: v)
		{
			cmd->run(bot, curr);
			if(curr != NULL)
			{
				curr = curr-> next;
			}
		}

		while(curr->in.size() != 0)
		{
			// todo: clean
			bot->conn->send_privmsg(ev->target, curr->pop()->to_string());
		}

		delete i;
	}
	catch(CommandNotFoundException e)
	{
		bot->conn->send_privmsg(ev->target, "Command '" + e.command + "' not found!");
	}
	catch(PermissionDeniedException e)
	{
		bot->conn->send_privmsg(ev->target, "Permission denied for '" + e.command + "'!");
	}
	catch(CommandErrorException e)
	{
		bot->conn->send_privmsg(ev->target, "Command '" + e.command + "' threw error '" + e.err + "'!");
	}
}

bool check_permissions(Bot *bot, User *u, std::string target, std::string command);

std::tuple<CommandInfo*, std::vector<CommandBase*>> Command::parse(Bot *bot, IRCMessageEvent *ev)
{
	CommandInfo *info = new CommandInfo();
	CommandInfo *curr = info;

	std::vector<CommandBase*> v;

	std::string &s = ev->message;

	const int type_str = 0;
	const int type_delim = 1;

	std::vector<std::pair<int, std::string>> tokens;

	std::string tmp;

	size_t i = 0;

	bool quote = false;
	bool ignore = false;

	for(; i < s.length() ; i++)
	{
		char c = s[i];

		switch(c)
		{
			case '\"':
				if(quote)
				{
					tokens.push_back(std::make_pair(type_str, tmp));
					tmp.clear();
					ignore = true;
					quote = false;
				}
				else
				{
					quote = true;
				}
			break;

			case '|':
				tokens.push_back(std::make_pair(type_delim, ""));
				tmp.clear();
				ignore = true;
			break;

			case ' ':
				if(!ignore)
				{
					if(!quote && tmp != "")
					{
						tokens.push_back(std::make_pair(type_str, tmp));
						tmp.clear();
						ignore = true;
					}
					else
					{
						tmp += c;
					}
				}
			break;

			default:
				if(ignore) { ignore = false; }
				tmp += c;
			break;
		}
	}

	if(tmp != "")
	{
		tokens.push_back(std::make_pair(type_str, tmp));
	}

	bool cmd = true;

	for(auto a: tokens)
	{
		if(a.first == type_str)
		{
			if(cmd)
			{
				cmd = false;

				CommandBase *b = bot->get_command(a.second);
				if(b == NULL)
				{
					delete info;
					throw CommandNotFoundException(a.second);
				}

				if(!check_permissions(bot, ev->sender, ev->target, a.second))
				{
					throw PermissionDeniedException(a.second);
				}

				v.push_back(b);
			}
			else
			{
				curr->in.push_back(new StringData(a.second));
			}
		}
		else if(a.first == type_delim)
		{
			cmd = true;

			curr->sender = ev->sender;
			curr->target = ev->target;
			curr->cmd = v.back();

			curr->next = new CommandInfo();
			curr = curr->next;
		}
	}

	curr->cmd = v.back();
	curr->sender = ev->sender;
	curr->target = ev->target;

	curr->next = new CommandInfo();
	curr->next->sender = ev->sender;
	curr->next->target = ev->target;

	return std::make_tuple(info, v);
}

bool check_permissions(Bot *bot, User *u, std::string target, std::string command)
{
	if(!u->synced || u->account == "*")
	{
		return false;
	}

	std::shared_ptr<ConfigNode> v = bot->config->get("permissions." + command);

	if(v->type() == NodeType::List)
	{
		for(auto a : v->as_list())
		{
			std::string b = a;
			if(b == u->account)
			{
				return true;
			}
			else if(b.substr(0, 6) == "group/")
			{
				b = b.substr(6);

				if(b == "special/all")
				{
					return true;
				}
				else if(b == "special/none")
				{
					return false;
				}
				else if(b == "special/ops")
				{
					if(target[0] == '#')
					{
						Channel &c = bot->conn->get_channel(target);
						return c.users[u->nick].modes['o'];
					}
					else
					{
						return false;
					}
				}
				else if(b == "special/voice")
				{
					if(target[0] == '#')
					{
						Channel &c = bot->conn->get_channel(target);
						return c.users[u->nick].modes['v'];
					}
					else
					{
						return false;
					}
				}

				std::shared_ptr<ConfigNode> v2 = bot->config->get("groups." + b);
				if(v2->type() == NodeType::List)
				{
					for(auto c : v2->as_list())
					{
						if(c == u->account)
						{
							return true;
						}
					}
				}
			}
		}
	}

	return false;
}

CommandBase *Command::get_ptr(std::string n)
{
	std::cout << "Trying to get command " << n << std::endl;
	return NULL;
}<|endoftext|>