<commit_before>// Copyright (c) 2015, Baidu.com, Inc. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include <stdio.h>
#include <stdlib.h>
#include "util/random.h"
#include "util/testutil.h"

// Comma-separated list of operations to run in the specified order
//   Actual benchmarks:
//
//   seq       -- output N values in sequential key order
//   random    -- output N values in random key order
static const char* FLAGS_benchmarks =
    "seq,"
    "random,"
    ;

// Number of key/values to place in database
static int FLAGS_num = 1000000;

// Number of read operations to do.  If negative, do FLAGS_num reads.
static int FLAGS_reads = -1;

// Size of each key
static int FLAGS_key_size = 16;

// Size of each value
static int FLAGS_value_size = 100;

// Arrange to generate values that shrink to this fraction of
// their original size after compression
static double FLAGS_compression_ratio = 0.5;

// Number of tablets
static int FLAGS_tablet_num = 1;

// CF list in format: "cf0:q1,cf1:q2..."
static std::string FLAGS_cf_list = "";

// Seq mode start key
static int FLAGS_start_key = 0;

// Value generator's seed
static int FLAGS_value_seed = 301;

// Key generator's seed
static int FLAGS_key_seed = 301;

namespace leveldb {

// Helper for quickly generating random data.
namespace {
class RandomGenerator {
 private:
  std::string data_;
  int pos_;

 public:
  RandomGenerator() {
    // We use a limited amount of data over and over again and ensure
    // that it is larger than the compression window (32KB), and also
    // large enough to serve all typical value sizes we want to write.
    Random rnd(FLAGS_value_seed);
    std::string piece;
    while (data_.size() < 1048576) {
      // Add a short fragment that is as compressible as specified
      // by FLAGS_compression_ratio.
      test::CompressibleString(&rnd, FLAGS_compression_ratio, 100, &piece);
      data_.append(piece);
    }
    pos_ = 0;
  }

  Slice Generate(int len) {
    if (pos_ + len > static_cast<int>(data_.size())) {
      pos_ = 0;
      assert(len < static_cast<int>(data_.size()));
    }
    pos_ += len;
    return Slice(data_.data() + pos_ - len, len);
  }
};

}  // namespace

class Benchmark {
 private:
  int num_;
  int reads_;
  double start_;
  int64_t bytes_;
  std::string message_;
  RandomGenerator gen_;
  Random rand_;
  Random** tablet_rand_vector_;

  // State kept for progress messages
  int done_;
  int next_report_;     // When to report next

  void Start() {
    start_ = Env::Default()->NowMicros() * 1e-6;
    bytes_ = 0;
    message_.clear();
    done_ = 0;
    next_report_ = 100;
  }

  void Stop(const Slice& name) {
    double finish = Env::Default()->NowMicros() * 1e-6;

    // Pretend at least one op was done in case we are running a benchmark
    // that does not call FinishedSingleOp().
    if (done_ < 1) done_ = 1;

    if (bytes_ > 0) {
      char rate[100];
      snprintf(rate, sizeof(rate), "%6.1f MB/s",
               (bytes_ / 1048576.0) / (finish - start_));
      if (!message_.empty()) {
        message_  = std::string(rate) + " " + message_;
      } else {
        message_ = rate;
      }
    }

    fprintf(stderr, "%-12s : %11.3f micros/op;%s%s\n",
            name.ToString().c_str(),
            (finish - start_) * 1e6 / done_,
            (message_.empty() ? "" : " "),
            message_.c_str());
    fflush(stderr);
  }

 public:
  enum Order {
    SEQUENTIAL,
    RANDOM
  };

  Benchmark()
  : num_(FLAGS_num),
    reads_(FLAGS_reads < 0 ? FLAGS_num : FLAGS_reads),
    bytes_(0),
    rand_(FLAGS_key_seed) {
    tablet_rand_vector_ = new Random*[FLAGS_tablet_num];
    for (int i = 0; i < FLAGS_tablet_num; i++) {
      tablet_rand_vector_[i] = new Random(FLAGS_key_seed);
    }
  }

  ~Benchmark() {
    for (int i = 0; i < FLAGS_tablet_num; i++) {
      delete tablet_rand_vector_[i];
    }
    delete[] tablet_rand_vector_;
  }

  void Run() {
    // parse cf list
    std::vector<std::string> cfs;
    if (FLAGS_cf_list != "") {
      std::string buffer = FLAGS_cf_list;
      size_t start_index = 0;
      size_t end_index = buffer.find(",");
      while (end_index != std::string::npos) {
        cfs.push_back(buffer.substr(start_index, end_index - start_index));
        start_index = end_index + 1;
        end_index = buffer.find(",", start_index);
      }
      cfs.push_back(buffer.substr(start_index));
    }

    const char* benchmarks = FLAGS_benchmarks;
    while (benchmarks != NULL) {
      const char* sep = strchr(benchmarks, ',');
      Slice name;
      if (sep == NULL) {
        name = benchmarks;
        benchmarks = NULL;
      } else {
        name = Slice(benchmarks, sep - benchmarks);
        benchmarks = sep + 1;
      }

      Start();

      bool known = true;
      if (name == Slice("seq")) {
        Output(SEQUENTIAL, num_, FLAGS_value_size, cfs);
      } else if (name == Slice("random")) {
        Output(RANDOM, num_, FLAGS_value_size, cfs);
      } else {
        known = false;
        if (name != Slice()) {  // No error message for empty name
          fprintf(stderr, "unknown benchmark '%s'\n", name.ToString().c_str());
        }
      }
      if (known) {
        Stop(name);
      }
    }
  }

 private:

  void Output(Order order, int num_entries, int value_size, std::vector<std::string>& cfs) {
    if (num_entries != num_) {
      char msg[100];
      snprintf(msg, sizeof(msg), "(%d ops)", num_entries);
      message_ = msg;
    }
    char ts[10];
    snprintf(ts, sizeof(ts), "%d", FLAGS_value_seed);

    // Write to database
    int i = FLAGS_start_key;
    int end_key = i + num_entries;
    for (; i < end_key; i++)
    {
      const int t = rand_.Next() % FLAGS_tablet_num;
      const int k = (order == SEQUENTIAL) ? i : (tablet_rand_vector_[t]->Next());
      char key[10000];
      snprintf(key, sizeof(key), "%06d%0*d", t, FLAGS_key_size - 6, k);
      bytes_ += value_size + strlen(key);
      if (cfs.empty() == true) {
        fprintf(stdout, "%s\t%s\n", key, gen_.Generate(value_size).ToString().c_str());
      } else {
        for (size_t j = 0; j < cfs.size(); ++j) {
          fprintf(stdout, "%s\t%s\t%s\t%s\n", key, gen_.Generate(value_size).ToString().c_str(), cfs[j].c_str(), ts);
        }
      }
    }
  }
};

}  // namespace leveldb

int main(int argc, char** argv) {
  for (int i = 1; i < argc; i++) {
    double d;
    int n;
    char junk;
    char cf_list[1024];
    if (leveldb::Slice(argv[i]).starts_with("--benchmarks=")) {
      FLAGS_benchmarks = argv[i] + strlen("--benchmarks=");
    } else if (sscanf(argv[i], "--compression_ratio=%lf%c", &d, &junk) == 1) {
      FLAGS_compression_ratio = d;
    } else if (sscanf(argv[i], "--num=%d%c", &n, &junk) == 1) {
      FLAGS_num = n;
    } else if (sscanf(argv[i], "--reads=%d%c", &n, &junk) == 1) {
      FLAGS_reads = n;
    } else if (sscanf(argv[i], "--key_size=%d%c", &n, &junk) == 1 && n < 10000) {
      FLAGS_key_size = n;
    } else if (sscanf(argv[i], "--value_size=%d%c", &n, &junk) == 1) {
      FLAGS_value_size = n;
    } else if (sscanf(argv[i], "--tablet_num=%d%c", &n, &junk) == 1) {
      FLAGS_tablet_num = n;
    } else if (sscanf(argv[i], "--cf=%s", cf_list) == 1) {
      FLAGS_cf_list = std::string(cf_list);
    } else if (sscanf(argv[i], "--start_key=%d%c", &n, &junk) == 1) {
      FLAGS_start_key = n;
    } else if (sscanf(argv[i], "--value_seed=%d%c", &n, &junk) == 1) {
      FLAGS_value_seed = n;
    } else if (sscanf(argv[i], "--key_seed=%d%c", &n, &junk) == 1) {
      FLAGS_key_seed = n;
    } else {
      fprintf(stderr, "Invalid flag '%s'\n", argv[i]);
      exit(1);
    }
  }

  leveldb::Benchmark benchmark;
  benchmark.Run();
  return 0;
}
<commit_msg>issue=#492 tera_bench & sev seq write with step<commit_after>// Copyright (c) 2015, Baidu.com, Inc. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include <stdio.h>
#include <stdlib.h>
#include "util/random.h"
#include "util/testutil.h"

// Comma-separated list of operations to run in the specified order
//   Actual benchmarks:
//
//   seq       -- output N values in sequential key order
//   random    -- output N values in random key order
static const char* FLAGS_benchmarks =
    "seq,"
    "random,"
    ;

// Number of key/values to place in database
static int FLAGS_num = 1000000;

// Number of read operations to do.  If negative, do FLAGS_num reads.
static int FLAGS_reads = -1;

// Size of each key
static int FLAGS_key_size = 16;

// Size of each value
static int FLAGS_value_size = 100;

// Arrange to generate values that shrink to this fraction of
// their original size after compression
static double FLAGS_compression_ratio = 0.5;

// Number of tablets
static int FLAGS_tablet_num = 1;

// CF list in format: "cf0:q1,cf1:q2..."
static std::string FLAGS_cf_list = "";

// Seq mode start key
static int FLAGS_start_key = 0;

// Value generator's seed
static int FLAGS_value_seed = 301;

// Key generator's seed
static int FLAGS_key_seed = 301;

// Key step, used in seq key generation
static int FLAGS_key_step = 1;

namespace leveldb {

// Helper for quickly generating random data.
namespace {
class RandomGenerator {
 private:
  std::string data_;
  int pos_;

 public:
  RandomGenerator() {
    // We use a limited amount of data over and over again and ensure
    // that it is larger than the compression window (32KB), and also
    // large enough to serve all typical value sizes we want to write.
    Random rnd(FLAGS_value_seed);
    std::string piece;
    while (data_.size() < 1048576) {
      // Add a short fragment that is as compressible as specified
      // by FLAGS_compression_ratio.
      test::CompressibleString(&rnd, FLAGS_compression_ratio, 100, &piece);
      data_.append(piece);
    }
    pos_ = 0;
  }

  Slice Generate(int len) {
    if (pos_ + len > static_cast<int>(data_.size())) {
      pos_ = 0;
      assert(len < static_cast<int>(data_.size()));
    }
    pos_ += len;
    return Slice(data_.data() + pos_ - len, len);
  }
};

}  // namespace

class Benchmark {
 private:
  int num_;
  int reads_;
  double start_;
  int64_t bytes_;
  std::string message_;
  RandomGenerator gen_;
  Random rand_;
  Random** tablet_rand_vector_;

  // State kept for progress messages
  int done_;
  int next_report_;     // When to report next

  void Start() {
    start_ = Env::Default()->NowMicros() * 1e-6;
    bytes_ = 0;
    message_.clear();
    done_ = 0;
    next_report_ = 100;
  }

  void Stop(const Slice& name) {
    double finish = Env::Default()->NowMicros() * 1e-6;

    // Pretend at least one op was done in case we are running a benchmark
    // that does not call FinishedSingleOp().
    if (done_ < 1) done_ = 1;

    if (bytes_ > 0) {
      char rate[100];
      snprintf(rate, sizeof(rate), "%6.1f MB/s",
               (bytes_ / 1048576.0) / (finish - start_));
      if (!message_.empty()) {
        message_  = std::string(rate) + " " + message_;
      } else {
        message_ = rate;
      }
    }

    fprintf(stderr, "%-12s : %11.3f micros/op;%s%s\n",
            name.ToString().c_str(),
            (finish - start_) * 1e6 / done_,
            (message_.empty() ? "" : " "),
            message_.c_str());
    fflush(stderr);
  }

 public:
  enum Order {
    SEQUENTIAL,
    RANDOM
  };

  Benchmark()
  : num_(FLAGS_num),
    reads_(FLAGS_reads < 0 ? FLAGS_num : FLAGS_reads),
    bytes_(0),
    rand_(FLAGS_key_seed) {
    tablet_rand_vector_ = new Random*[FLAGS_tablet_num];
    for (int i = 0; i < FLAGS_tablet_num; i++) {
      tablet_rand_vector_[i] = new Random(FLAGS_key_seed);
    }
  }

  ~Benchmark() {
    for (int i = 0; i < FLAGS_tablet_num; i++) {
      delete tablet_rand_vector_[i];
    }
    delete[] tablet_rand_vector_;
  }

  void Run() {
    // parse cf list
    std::vector<std::string> cfs;
    if (FLAGS_cf_list != "") {
      std::string buffer = FLAGS_cf_list;
      size_t start_index = 0;
      size_t end_index = buffer.find(",");
      while (end_index != std::string::npos) {
        cfs.push_back(buffer.substr(start_index, end_index - start_index));
        start_index = end_index + 1;
        end_index = buffer.find(",", start_index);
      }
      cfs.push_back(buffer.substr(start_index));
    }

    const char* benchmarks = FLAGS_benchmarks;
    while (benchmarks != NULL) {
      const char* sep = strchr(benchmarks, ',');
      Slice name;
      if (sep == NULL) {
        name = benchmarks;
        benchmarks = NULL;
      } else {
        name = Slice(benchmarks, sep - benchmarks);
        benchmarks = sep + 1;
      }

      Start();

      bool known = true;
      if (name == Slice("seq")) {
        Output(SEQUENTIAL, num_, FLAGS_value_size, cfs);
      } else if (name == Slice("random")) {
        Output(RANDOM, num_, FLAGS_value_size, cfs);
      } else {
        known = false;
        if (name != Slice()) {  // No error message for empty name
          fprintf(stderr, "unknown benchmark '%s'\n", name.ToString().c_str());
        }
      }
      if (known) {
        Stop(name);
      }
    }
  }

 private:

  void Output(Order order, int num_entries, int value_size, std::vector<std::string>& cfs) {
    if (num_entries != num_) {
      char msg[100];
      snprintf(msg, sizeof(msg), "(%d ops)", num_entries);
      message_ = msg;
    }
    char ts[10];
    snprintf(ts, sizeof(ts), "%d", FLAGS_value_seed);

    // Write to database
    int i = FLAGS_start_key;
    int end_key = i + num_entries * FLAGS_key_step;
    for (; i < end_key; i += FLAGS_key_step)
    {
      const int t = rand_.Next() % FLAGS_tablet_num;
      const int k = (order == SEQUENTIAL) ? i : (tablet_rand_vector_[t]->Next());
      char key[10000];
      snprintf(key, sizeof(key), "%06d%0*d", t, FLAGS_key_size - 6, k);
      bytes_ += value_size + strlen(key);
      if (cfs.empty() == true) {
        fprintf(stdout, "%s\t%s\n", key, gen_.Generate(value_size).ToString().c_str());
      } else {
        for (size_t j = 0; j < cfs.size(); ++j) {
          fprintf(stdout, "%s\t%s\t%s\t%s\n", key, gen_.Generate(value_size).ToString().c_str(), cfs[j].c_str(), ts);
        }
      }
    }
  }
};

}  // namespace leveldb

int main(int argc, char** argv) {
  for (int i = 1; i < argc; i++) {
    double d;
    int n;
    char junk;
    char cf_list[1024];
    if (leveldb::Slice(argv[i]).starts_with("--benchmarks=")) {
      FLAGS_benchmarks = argv[i] + strlen("--benchmarks=");
    } else if (sscanf(argv[i], "--compression_ratio=%lf%c", &d, &junk) == 1) {
      FLAGS_compression_ratio = d;
    } else if (sscanf(argv[i], "--num=%d%c", &n, &junk) == 1) {
      FLAGS_num = n;
    } else if (sscanf(argv[i], "--reads=%d%c", &n, &junk) == 1) {
      FLAGS_reads = n;
    } else if (sscanf(argv[i], "--key_size=%d%c", &n, &junk) == 1 && n < 10000) {
      FLAGS_key_size = n;
    } else if (sscanf(argv[i], "--value_size=%d%c", &n, &junk) == 1) {
      FLAGS_value_size = n;
    } else if (sscanf(argv[i], "--tablet_num=%d%c", &n, &junk) == 1) {
      FLAGS_tablet_num = n;
    } else if (sscanf(argv[i], "--cf=%s", cf_list) == 1) {
      FLAGS_cf_list = std::string(cf_list);
    } else if (sscanf(argv[i], "--start_key=%d%c", &n, &junk) == 1) {
      FLAGS_start_key = n;
    } else if (sscanf(argv[i], "--value_seed=%d%c", &n, &junk) == 1) {
      FLAGS_value_seed = n;
    } else if (sscanf(argv[i], "--key_seed=%d%c", &n, &junk) == 1) {
      FLAGS_key_seed = n;
    } else if (sscanf(argv[i], "--key_step=%d%c", &n, &junk) == 1) {
      FLAGS_key_step = n;
    } else {
      fprintf(stderr, "Invalid flag '%s'\n", argv[i]);
      exit(1);
    }
  }

  leveldb::Benchmark benchmark;
  benchmark.Run();
  return 0;
}
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-05-13 14:52:01 +0200 (Mi, 13. Mai 2009) $
Version:   $Revision: 17230 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

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

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

#include "mitkNavigationDataPlayer.h"
#include "mitkNavigationData.h"

#include "mitkTestingMacros.h"
#include "mitkStandardFileLocations.h"
#include "mitkTimeStamp.h"

#include <iostream>
#include <sstream>

/**Documentation
 *  test for the class "NavigationDataPlayer".
 */
int mitkNavigationDataPlayerTest(int /* argc */, char* /*argv*/[])
{
  MITK_TEST_BEGIN("NavigationDataPlayer");
  std::string tmp = "";

  // let's create an object of our class
  mitk::NavigationDataPlayer::Pointer player = mitk::NavigationDataPlayer::New();

  // first test: did this work?
  // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
  // it makes no sense to continue without an object.
  MITK_TEST_CONDITION_REQUIRED(player.IsNotNull(), "Testing instantiation");

  std::string file = mitk::StandardFileLocations::GetInstance()->FindFile("NavigationDataTestData.xml", "Modules/IGT/Testing/Data");

  player->SetFileName( file );

  MITK_TEST_CONDITION_REQUIRED( strcmp(player->GetFileName(), file.c_str()) == 0, "Testing SetFileName and GetFileName");

  player->SetStream( mitk::NavigationDataPlayer::NormalFile );
  player->StartPlaying();
  player->Update();
  player->StopPlaying();

  mitk::NavigationData::Pointer nd = player->GetOutput();
  mitk::Point3D pnt;
  pnt[0] = 1;
  pnt[1] = 0;
  pnt[2] = 3;

  MITK_TEST_CONDITION_REQUIRED( nd->GetPosition() == pnt, "Testing position of replayed NavigaionData" );
  //MITK_TEST_CONDITION_REQUIRED( nd->GetTimeStamp() == 3068.94, "Testing for correct TimeStamp" );

  std::vector<double> times, refTimes;
  refTimes.resize(5);
  refTimes[0] = 3.9;
  refTimes[1] = 83.6;
  refTimes[2] = 174.4;
  refTimes[3] = 275.0;
  refTimes[4] = 385.39;

  mitk::TimeStamp::Pointer timer = mitk::TimeStamp::GetInstance();
  timer->Initialize();

  itk::Object::Pointer obj = itk::Object::New();
  timer->Start( obj );

  mitk::Point3D oldPos;
  oldPos[0] = 1;
  oldPos[1] = 0;
  oldPos[2] = 3;
  //pnt = oldPos;
  player->StartPlaying();
  while( times.size()<5 )
  {
    player->Update();
    pnt = nd->GetPosition();
    if ( pnt != oldPos )
    {
      times.push_back( timer->GetElapsed(obj) );
      oldPos = pnt;
    }
  }

  // if this test fails, it may be because the dartclient runs on a virtual machine.
  // Under these circumstances, it may be impossible to achieve a time-accuracy of 10ms
  for ( int i=0;i<5;i++ )
  {
    std::cout << "ref: " << refTimes[i] << "  /  time elapsed: " << times[i] << std::endl;
    MITK_TEST_CONDITION_REQUIRED( (times[i]>refTimes[i]-10 && times[i]<refTimes[i]+10), "checking for more or less correct time-line"  );
  }

  // always end with this!
  MITK_TEST_END();
}
<commit_msg>COMP: added 5 ms for time critical test <commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-05-13 14:52:01 +0200 (Mi, 13. Mai 2009) $
Version:   $Revision: 17230 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

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

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

#include "mitkNavigationDataPlayer.h"
#include "mitkNavigationData.h"

#include "mitkTestingMacros.h"
#include "mitkStandardFileLocations.h"
#include "mitkTimeStamp.h"

#include <iostream>
#include <sstream>

/**Documentation
 *  test for the class "NavigationDataPlayer".
 */
int mitkNavigationDataPlayerTest(int /* argc */, char* /*argv*/[])
{
  MITK_TEST_BEGIN("NavigationDataPlayer");
  std::string tmp = "";

  // let's create an object of our class
  mitk::NavigationDataPlayer::Pointer player = mitk::NavigationDataPlayer::New();

  // first test: did this work?
  // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
  // it makes no sense to continue without an object.
  MITK_TEST_CONDITION_REQUIRED(player.IsNotNull(), "Testing instantiation");

  std::string file = mitk::StandardFileLocations::GetInstance()->FindFile("NavigationDataTestData.xml", "Modules/IGT/Testing/Data");

  player->SetFileName( file );

  MITK_TEST_CONDITION_REQUIRED( strcmp(player->GetFileName(), file.c_str()) == 0, "Testing SetFileName and GetFileName");

  player->SetStream( mitk::NavigationDataPlayer::NormalFile );
  player->StartPlaying();
  player->Update();
  player->StopPlaying();

  mitk::NavigationData::Pointer nd = player->GetOutput();
  mitk::Point3D pnt;
  pnt[0] = 1;
  pnt[1] = 0;
  pnt[2] = 3;

  MITK_TEST_CONDITION_REQUIRED( nd->GetPosition() == pnt, "Testing position of replayed NavigaionData" );
  //MITK_TEST_CONDITION_REQUIRED( nd->GetTimeStamp() == 3068.94, "Testing for correct TimeStamp" );

  std::vector<double> times, refTimes;
  refTimes.resize(5);
  refTimes[0] = 3.9;
  refTimes[1] = 83.6;
  refTimes[2] = 174.4;
  refTimes[3] = 275.0;
  refTimes[4] = 385.39;

  mitk::TimeStamp::Pointer timer = mitk::TimeStamp::GetInstance();
  timer->Initialize();

  itk::Object::Pointer obj = itk::Object::New();
  timer->Start( obj );

  mitk::Point3D oldPos;
  oldPos[0] = 1;
  oldPos[1] = 0;
  oldPos[2] = 3;
  //pnt = oldPos;
  player->StartPlaying();
  while( times.size()<5 )
  {
    player->Update();
    pnt = nd->GetPosition();
    if ( pnt != oldPos )
    {
      times.push_back( timer->GetElapsed(obj) );
      oldPos = pnt;
    }
  }

  // if this test fails, it may be because the dartclient runs on a virtual machine.
  // Under these circumstances, it may be impossible to achieve a time-accuracy of 10ms
  for ( int i=0;i<5;i++ )
  {
    std::cout << "ref: " << refTimes[i] << "  /  time elapsed: " << times[i] << std::endl;
    MITK_TEST_CONDITION_REQUIRED( (times[i]>refTimes[i]-15 && times[i]<refTimes[i]+15), "checking for more or less correct time-line"  );
  }

  // always end with this!
  MITK_TEST_END();
}
<|endoftext|>


<commit_before>/*
farrtl.cpp

    : new/delete/malloc/realloc/free
*/

/* Revision: 1.20 09.08.2004 $ */

/*
Modify:
  09.08.2004 SKV
    - ftell64, fseek64 fix.
  06.08.2004 SKV
    ! see 01825.MSVCRT.txt
  01.06.2003 SVS
    ! FAR_CreateFile   farrtl.cpp  farwinapi.cpp
  25.02.2003 SVS
    !   CallNewDelete/CallMallocFree
  20.02.2003 SVS
    ! xf_*  __cdecl, ..   strdup.c, del.cpp  new.cpp
  26.01.2003 IS
    + FAR_CreateFile -   CreateFile,
        CreateFile
  21.01.2003 SVS
    + xf_malloc,xf_realloc,xf_free -   malloc,realloc,free
            xf_*  .
  21.03.2002 SVS
    !   FarBsearch, FarSscanf, FarSprintf, FarQsortEx,
      FarQsort, FarAtoi64, FarAtoi, FarItoa64, FarItoa  mix.cpp
       farrtl.cpp
  27.02.2002 SVS
    !      cmem.cpp
  26.02.2002 SVS
    -   RTL VC (    V64  MSVC!)
  22.02.2002 SVS
    !  fseek64  ftell64 ( ..   WINAPI)
  10.07.2001 SVS
    -      "fn.hpp" :-(
  31.10.2000 SVS
    !      _nfile  (BC5.5.1 )
  29.08.2000 SVS
    !     seek  __int64
  14.08.2000 SVS
    +   seek  __int64
  19.07.2000 SVS
    +   getdisk
      -     getdisk  BC & VC
        AltFx    UNC
  13.07.2000 SVS (  VVM)
    ! VVM>    -  block = NULL,  95/98
      VVM> ,   ...
      VVM> if(!size)
      VVM>   HeapFree(FARHeapForNew,0,block);
  12.07.2000 IS
    !  new  "void *p"  "void *p=NULL" (SVS   ...)
    !   NULL ""  delete  free
  12.07.2000 SVS
    !  MEM_DELTA  4095
    +   new/delete by IS
    +  cmem    .
  11.07.2000 SVS
    !   ( )  .
  05.07.2000 IS
    !   ,    ,
      ,   new/delete :-(((
  04.07.2000 SVS
    !     !
  03.07.2000 IS
    !
*/

#include "headers.hpp"
#pragma hdrstop
#include "fn.hpp"
#include "farconst.hpp"

/* $ 19.07.2000 SVS
  - -     getdisk  BC & VC
      AltFx    UNC
        farrtl.cpp
*/
int _cdecl getdisk(void)
{
  unsigned drive;
  char    buf[MAX_PATH];

  /* Use GetCurrentDirectory to get the current directory path, then
   * parse the drive name.
   */
  GetCurrentDirectory(sizeof(buf), buf);    /* ignore errors */
  drive = buf[0] >= 'a' ? buf[0] - 'a' + 1 : buf[0] - 'A' + 1;
  return (int)drive - 1;
}
/* SVS $*/

/* $ 14.08.2000 SVS
    +   seek  __int64
*/
#if defined(__BORLANDC__)
//#include <windows.h>
//#include <stdio.h>
//#include <stdlib.h>
//#include <fcntl.h>

#ifdef __cplusplus
extern "C" {
#endif

int  __IOerror    (int  __doserror);   /* returns -1 */
int  __NTerror     (void);              /* returns -1 */

#ifdef __cplusplus
};
#endif

#define RETURN(code)    {rc=(code); goto exit;}

//extern unsigned  _nfile;

/* Array of open file flags.
 */
extern unsigned int _openfd[];

/* Array of open file handles (not used on OS/2).
 */
extern long _handles[];

static int Displacement (FILE *fp)
{
  register    level;
  int         disp;
  register    unsigned char *P;

  if (fp->level < 0)
    disp = level = fp->bsize + fp->level + 1;
  else
    disp = level = fp->level;

  if (fp->flags & _F_BIN)
    return disp;

  P = fp->curp;

  if (fp->level < 0)          /* If writing */
  {
    while (level--)
     if ('\n' == *--P)
       disp++;
  }
  else                        /* Else reading */
  {
    while (level--)
     if ('\n' == *P++)
       disp++;
  }

  return  disp;
}

static __int64 __lseek64(int fd, __int64 offset, int kind)
{
  FAR_INT64 Number;

  DWORD  method;

  if ((unsigned)fd >= _nfile)
    return (__int64)__IOerror(ERROR_INVALID_HANDLE);

  /* Translate the POSIX seek type to the NT method.
   */
  switch (kind)
  {
    case SEEK_SET:
      method = FILE_BEGIN;
      break;
    case SEEK_CUR:
      method = FILE_CURRENT;
      break;
    case SEEK_END:
      method = FILE_END;
      break;
    default:
      return ((__int64)__IOerror(ERROR_INVALID_FUNCTION));
  }

  _openfd[fd] &= ~_O_EOF;      /* forget about ^Z      */

  Number.Part.HighPart=offset>>32;

  Number.Part.LowPart = SetFilePointer((HANDLE)_handles[fd], (DWORD)offset, &Number.Part.HighPart, method);
  if (Number.Part.LowPart == -1 && GetLastError() != NO_ERROR)
  {
    __NTerror();        /* set errno */
    Number.i64=-1;
  }

  return Number.i64;
}

int fseek64 (FILE *fp, __int64 offset, int whence)
{
  if (fflush (fp))
    return (EOF);

  if (SEEK_CUR == whence && fp->level > 0)
    offset -= Displacement (fp);

  fp->flags &= ~(_F_OUT | _F_IN | _F_EOF);
  fp->level = 0;
  fp->curp = fp->buffer;

  return (__lseek64 (fp->fd, offset, whence) == -1L) ? EOF : 0;
}

__int64 ftell64(FILE *fp)
{
  __int64  oldpos, rc;

  if ((rc = __lseek64( fp->fd, 0, SEEK_CUR )) != -1)
  {
    if (fp->level < 0)  /* if writing */
    {
      if (_openfd[fp->fd] & O_APPEND)
      {
        /* In append mode, find out how big the file is,
         * and add the number of buffered bytes to that.
         */
        oldpos = rc;
        if ((rc = __lseek64( fp->fd, 0, SEEK_END )) == -1)
          return rc;
        if (__lseek64( fp->fd, oldpos, SEEK_SET ) == -1)
          return -1;
      }
      rc += Displacement(fp);
    }
    else
      rc -= Displacement(fp);
  }
  return rc;
}

#else

#include <io.h>
//extern "C"{
//_CRTIMP __int64 __cdecl _ftelli64 (FILE *str);
//_CRTIMP int __cdecl _fseeki64 (FILE *stream, __int64 offset, int whence);
//};

__int64 ftell64(FILE *fp)
{
  //return _ftelli64(fp);
  //return _telli64(fileno(fp));
  fpos_t pos;
  if(fgetpos(fp,&pos)!=0)return 0;
  return pos;
}

int fseek64 (FILE *fp, __int64 offset, int whence)
{
  //return _fseeki64(fp,offset,whence);
  //return _lseeki64(fileno(fp),offset,whence);
  switch(whence)
  {
    case SEEK_SET:return fsetpos(fp,&offset);
    case SEEK_CUR:
    {
      fpos_t pos;
      fgetpos(fp,&pos);
      pos+=offset;
      return fsetpos(fp,&pos);
    }
    case SEEK_END:
    {
      fpos_t pos;
      fseek(fp,0,SEEK_END);
      fgetpos(fp,&pos);
      pos+=offset;
      return fsetpos(fp,&pos);
    }
  }
  return -1;
}

#endif
/* SVS $*/

/* $ 25.07.2000 SVS
       ,   WINAPI
*/
char *WINAPI FarItoa(int value, char *string, int radix)
{
  if(string)
    return itoa(value,string,radix);
  return NULL;
}
/* $ 28.08.2000 SVS
  + FarItoa64
*/
char *WINAPI FarItoa64(__int64 value, char *string, int radix)
{
  if(string)
    return _i64toa(value, string, radix);
  return NULL;
}
/* SVS $ */
int WINAPI FarAtoi(const char *s)
{
  if(s)
    return atoi(s);
  return 0;
}
__int64 WINAPI FarAtoi64(const char *s)
{
  if(s)
    return _atoi64(s);
  return 0i64;
}

void WINAPI FarQsort(void *base, size_t nelem, size_t width,
                     int (__cdecl *fcmp)(const void *, const void *))
{
  if(base && fcmp)
    far_qsort(base,nelem,width,fcmp);
}

/* $ 24.03.2001 tran
    ...*/
void WINAPI FarQsortEx(void *base, size_t nelem, size_t width,
                     int (__cdecl *fcmp)(const void *, const void *,void *user),void *user)
{
  if(base && fcmp)
    qsortex((char*)base,nelem,width,fcmp,user);
}
/* tran $ */

int WINAPIV FarSprintf(char *buffer,const char *format,...)
{
  int ret=0;
  if(buffer && format)
  {
    va_list argptr;
    va_start(argptr,format);
    ret=vsprintf(buffer,format,argptr);
    va_end(argptr);
  }
  return ret;
}

#ifndef FAR_MSVCRT
/* $ 29.08.2000 SVS
   -    FarSscanf
    - ..  VC  vsscanf,    (
    VC sscanf  ""
*/
#if defined(_MSC_VER)
extern "C" {
int __cdecl _input (FILE *stream,const unsigned char *format,va_list arglist);
};
#endif

int WINAPIV FarSscanf(const char *buffer, const char *format,...)
{
  if(!buffer || !format)
    return 0;
#if defined(_MSC_VER)
  //    sscanf :-)
  va_list arglist;
  FILE str;
  FILE *infile = &str;
  int retval;

  va_start(arglist, format);

  infile->_flag = _IOREAD|_IOSTRG|_IOMYBUF;
  infile->_ptr = infile->_base = (char *) buffer;
  infile->_cnt = strlen(buffer);

  retval = (_input(infile,(const unsigned char *)format,arglist));

  return(retval);
#else
  va_list argptr;
  va_start(argptr,format);
  int ret=vsscanf(buffer,format,argptr);
  va_end(argptr);
  return ret;
#endif
}
/* 29.08.2000 SVS $ */
/* SVS $ */

#endif

/* $ 07.09.2000 SVS
    FarBsearch   ( bsearch)
*/
void *WINAPI FarBsearch(const void *key, const void *base, size_t nelem, size_t width, int (__cdecl *fcmp)(const void *, const void *))
{
  if(key && fcmp && base)
    return bsearch(key,base,nelem,width,fcmp);
  return NULL;
}
/* SVS $ */

#if defined(SYSLOG)
extern long CallMallocFree;
#endif

void __cdecl  xf_free(void *__block)
{
#if defined(SYSLOG)
  CallMallocFree--;
#endif
  free(__block);
}

void *__cdecl xf_malloc(size_t __size)
{
  void *Ptr=malloc(__size);
#if defined(SYSLOG)
  CallMallocFree++;
#endif
  return Ptr;
}

void *__cdecl xf_realloc(void *__block, size_t __size)
{
  void *Ptr=realloc(__block,__size);
#if defined(SYSLOG)
  if(!__block)
    CallMallocFree++;
#endif
  return Ptr;
}
<commit_msg>FAR patch 01835.BugZ1170 Дата              : 09.10.2004 Сделал            : Valentin Skirdin Описание          : BugZ#1170 Измененные файлы  : farrtl.cpp Новые файлы       : Удаленные файлы   : Состав            : 01835.BugZ1170.txt                     farrtl.cpp.1835.diff Основан на патче  : 1834 Дополнение        :<commit_after>/*
farrtl.cpp

    : new/delete/malloc/realloc/free
*/

/* Revision: 1.21 09.10.2004 $ */

/*
Modify:
  09.10.2004 SVS
    - BugZ#1170 - Strange viewer behaviour if filesize > 0xFFFFFFFF
  09.08.2004 SKV
    - ftell64, fseek64 fix.
  06.08.2004 SKV
    ! see 01825.MSVCRT.txt
  01.06.2003 SVS
    ! FAR_CreateFile   farrtl.cpp  farwinapi.cpp
  25.02.2003 SVS
    !   CallNewDelete/CallMallocFree
  20.02.2003 SVS
    ! xf_*  __cdecl, ..   strdup.c, del.cpp  new.cpp
  26.01.2003 IS
    + FAR_CreateFile -   CreateFile,
        CreateFile
  21.01.2003 SVS
    + xf_malloc,xf_realloc,xf_free -   malloc,realloc,free
            xf_*  .
  21.03.2002 SVS
    !   FarBsearch, FarSscanf, FarSprintf, FarQsortEx,
      FarQsort, FarAtoi64, FarAtoi, FarItoa64, FarItoa  mix.cpp
       farrtl.cpp
  27.02.2002 SVS
    !      cmem.cpp
  26.02.2002 SVS
    -   RTL VC (    V64  MSVC!)
  22.02.2002 SVS
    !  fseek64  ftell64 ( ..   WINAPI)
  10.07.2001 SVS
    -      "fn.hpp" :-(
  31.10.2000 SVS
    !      _nfile  (BC5.5.1 )
  29.08.2000 SVS
    !     seek  __int64
  14.08.2000 SVS
    +   seek  __int64
  19.07.2000 SVS
    +   getdisk
      -     getdisk  BC & VC
        AltFx    UNC
  13.07.2000 SVS (  VVM)
    ! VVM>    -  block = NULL,  95/98
      VVM> ,   ...
      VVM> if(!size)
      VVM>   HeapFree(FARHeapForNew,0,block);
  12.07.2000 IS
    !  new  "void *p"  "void *p=NULL" (SVS   ...)
    !   NULL ""  delete  free
  12.07.2000 SVS
    !  MEM_DELTA  4095
    +   new/delete by IS
    +  cmem    .
  11.07.2000 SVS
    !   ( )  .
  05.07.2000 IS
    !   ,    ,
      ,   new/delete :-(((
  04.07.2000 SVS
    !     !
  03.07.2000 IS
    !
*/

#include "headers.hpp"
#pragma hdrstop
#include "fn.hpp"
#include "farconst.hpp"

/* $ 19.07.2000 SVS
  - -     getdisk  BC & VC
      AltFx    UNC
        farrtl.cpp
*/
int _cdecl getdisk(void)
{
  unsigned drive;
  char    buf[MAX_PATH];

  /* Use GetCurrentDirectory to get the current directory path, then
   * parse the drive name.
   */
  GetCurrentDirectory(sizeof(buf), buf);    /* ignore errors */
  drive = buf[0] >= 'a' ? buf[0] - 'a' + 1 : buf[0] - 'A' + 1;
  return (int)drive - 1;
}
/* SVS $*/

/* $ 14.08.2000 SVS
    +   seek  __int64
*/
#if defined(__BORLANDC__)
//#include <windows.h>
//#include <stdio.h>
//#include <stdlib.h>
//#include <fcntl.h>

#ifdef __cplusplus
extern "C" {
#endif

int  __IOerror    (int  __doserror);   /* returns -1 */
int  __NTerror     (void);              /* returns -1 */

#ifdef __cplusplus
};
#endif

#define RETURN(code)    {rc=(code); goto exit;}

//extern unsigned  _nfile;

/* Array of open file flags.
 */
extern unsigned int _openfd[];

/* Array of open file handles (not used on OS/2).
 */
extern long _handles[];

static int Displacement (FILE *fp)
{
  register    level;
  int         disp;
  register    unsigned char *P;

  if (fp->level < 0)
    disp = level = fp->bsize + fp->level + 1;
  else
    disp = level = fp->level;

  if (fp->flags & _F_BIN)
    return disp;

  P = fp->curp;

  if (fp->level < 0)          /* If writing */
  {
    while (level--)
     if ('\n' == *--P)
       disp++;
  }
  else                        /* Else reading */
  {
    while (level--)
     if ('\n' == *P++)
       disp++;
  }

  return  disp;
}

static __int64 __lseek64(int fd, __int64 offset, int kind)
{
  FAR_INT64 Number;

  DWORD  method;

  if ((unsigned)fd >= _nfile)
    return (__int64)__IOerror(ERROR_INVALID_HANDLE);

  /* Translate the POSIX seek type to the NT method.
   */
  switch (kind)
  {
    case SEEK_SET:
      method = FILE_BEGIN;
      break;
    case SEEK_CUR:
      method = FILE_CURRENT;
      break;
    case SEEK_END:
      method = FILE_END;
      break;
    default:
      return ((__int64)__IOerror(ERROR_INVALID_FUNCTION));
  }

  _openfd[fd] &= ~_O_EOF;      /* forget about ^Z      */

  Number.Part.HighPart=offset>>32;

  Number.Part.LowPart = SetFilePointer((HANDLE)_handles[fd], (DWORD)offset, &Number.Part.HighPart, method);
  if (Number.Part.LowPart == -1 && GetLastError() != NO_ERROR)
  {
    __NTerror();        /* set errno */
    Number.i64=-1;
  }

  return Number.i64;
}

int fseek64 (FILE *fp, __int64 offset, int whence)
{
  if (fflush (fp))
    return (EOF);

  if (SEEK_CUR == whence && fp->level > 0)
    offset -= Displacement (fp);

  fp->flags &= ~(_F_OUT | _F_IN | _F_EOF);
  fp->level = 0;
  fp->curp = fp->buffer;

  return (__lseek64 (fp->fd, offset, whence) == -1L) ? EOF : 0;
}

__int64 ftell64(FILE *fp)
{
  __int64  oldpos, rc;

  if ((rc = __lseek64( fp->fd, 0, SEEK_CUR )) != -1)
  {
    if (fp->level < 0)  /* if writing */
    {
      if (_openfd[fp->fd] & O_APPEND)
      {
        /* In append mode, find out how big the file is,
         * and add the number of buffered bytes to that.
         */
        oldpos = rc;
        if ((rc = __lseek64( fp->fd, 0, SEEK_END )) == -1)
          return rc;
        if (__lseek64( fp->fd, oldpos, SEEK_SET ) == -1)
          return -1;
      }
      rc += Displacement(fp);
    }
    else
      rc -= Displacement(fp);
  }
  return rc;
}

#else

#include <io.h>
#ifndef FAR_MSVCRT
extern "C"{
_CRTIMP __int64 __cdecl _ftelli64 (FILE *str);
_CRTIMP int __cdecl _fseeki64 (FILE *stream, __int64 offset, int whence);
};
#endif

__int64 ftell64(FILE *fp)
{
#ifndef FAR_MSVCRT
  return _ftelli64(fp);
#else
  fpos_t pos;
  if(fgetpos(fp,&pos)!=0)return 0;
  return pos;
#endif
}

int fseek64 (FILE *fp, __int64 offset, int whence)
{
#ifndef FAR_MSVCRT
  return _fseeki64(fp,offset,whence);
#else
  switch(whence)
  {
    case SEEK_SET:return fsetpos(fp,&offset);
    case SEEK_CUR:
    {
      fpos_t pos;
      fgetpos(fp,&pos);
      pos+=offset;
      return fsetpos(fp,&pos);
    }
    case SEEK_END:
    {
      fpos_t pos;
      fseek(fp,0,SEEK_END);
      fgetpos(fp,&pos);
      pos+=offset;
      return fsetpos(fp,&pos);
    }
  }
  return -1;
#endif
}

#endif
/* SVS $*/

/* $ 25.07.2000 SVS
       ,   WINAPI
*/
char *WINAPI FarItoa(int value, char *string, int radix)
{
  if(string)
    return itoa(value,string,radix);
  return NULL;
}
/* $ 28.08.2000 SVS
  + FarItoa64
*/
char *WINAPI FarItoa64(__int64 value, char *string, int radix)
{
  if(string)
    return _i64toa(value, string, radix);
  return NULL;
}
/* SVS $ */
int WINAPI FarAtoi(const char *s)
{
  if(s)
    return atoi(s);
  return 0;
}
__int64 WINAPI FarAtoi64(const char *s)
{
  if(s)
    return _atoi64(s);
  return 0i64;
}

void WINAPI FarQsort(void *base, size_t nelem, size_t width,
                     int (__cdecl *fcmp)(const void *, const void *))
{
  if(base && fcmp)
    far_qsort(base,nelem,width,fcmp);
}

/* $ 24.03.2001 tran
    ...*/
void WINAPI FarQsortEx(void *base, size_t nelem, size_t width,
                     int (__cdecl *fcmp)(const void *, const void *,void *user),void *user)
{
  if(base && fcmp)
    qsortex((char*)base,nelem,width,fcmp,user);
}
/* tran $ */

int WINAPIV FarSprintf(char *buffer,const char *format,...)
{
  int ret=0;
  if(buffer && format)
  {
    va_list argptr;
    va_start(argptr,format);
    ret=vsprintf(buffer,format,argptr);
    va_end(argptr);
  }
  return ret;
}

#ifndef FAR_MSVCRT
/* $ 29.08.2000 SVS
   -    FarSscanf
    - ..  VC  vsscanf,    (
    VC sscanf  ""
*/
#if defined(_MSC_VER)
extern "C" {
int __cdecl _input (FILE *stream,const unsigned char *format,va_list arglist);
};
#endif

int WINAPIV FarSscanf(const char *buffer, const char *format,...)
{
  if(!buffer || !format)
    return 0;
#if defined(_MSC_VER)
  //    sscanf :-)
  va_list arglist;
  FILE str;
  FILE *infile = &str;
  int retval;

  va_start(arglist, format);

  infile->_flag = _IOREAD|_IOSTRG|_IOMYBUF;
  infile->_ptr = infile->_base = (char *) buffer;
  infile->_cnt = strlen(buffer);

  retval = (_input(infile,(const unsigned char *)format,arglist));

  return(retval);
#else
  va_list argptr;
  va_start(argptr,format);
  int ret=vsscanf(buffer,format,argptr);
  va_end(argptr);
  return ret;
#endif
}
/* 29.08.2000 SVS $ */
/* SVS $ */

#endif

/* $ 07.09.2000 SVS
    FarBsearch   ( bsearch)
*/
void *WINAPI FarBsearch(const void *key, const void *base, size_t nelem, size_t width, int (__cdecl *fcmp)(const void *, const void *))
{
  if(key && fcmp && base)
    return bsearch(key,base,nelem,width,fcmp);
  return NULL;
}
/* SVS $ */

#if defined(SYSLOG)
extern long CallMallocFree;
#endif

void __cdecl  xf_free(void *__block)
{
#if defined(SYSLOG)
  CallMallocFree--;
#endif
  free(__block);
}

void *__cdecl xf_malloc(size_t __size)
{
  void *Ptr=malloc(__size);
#if defined(SYSLOG)
  CallMallocFree++;
#endif
  return Ptr;
}

void *__cdecl xf_realloc(void *__block, size_t __size)
{
  void *Ptr=realloc(__block,__size);
#if defined(SYSLOG)
  if(!__block)
    CallMallocFree++;
#endif
  return Ptr;
}
<|endoftext|>


<commit_before>//
// Recursive Descent Parser
//

/**
 * Example Grammar:
 *
 *   tree ::= '(' ( | INT <tree> <tree> ) ')'
 */
enum TokenT {
	NONE,
	PAREN_OPEN,
	PAREN_CLOSE,
	INT
};

struct Token {
	TokenT t;
	int n;
	Token() {}
	Token(TokenT T): t(T) {}
	Token(TokenT T, int N): t(T), n(N) {}
};

struct Lexer {
	Reader &rr;
	bool has_tok;
	Token tok;
	Lexer(Reader &R): rr(R), has_tok(false) {}

	void read_token() {
		if (rr.has_next_int())
			tok = Token(INT, rr.next_int());
		else if (rr.has_next()) {
			char c = rr.next_char();
			switch (c) {
			case '(': tok = Token(PAREN_OPEN); break;
			case ')': tok = Token(PAREN_CLOSE); break;
			default: tok = Token(NONE);
			}
		}
		else
			tok = Token(NONE);

		has_tok = true;
	}

	TokenT peek() { if (! has_tok) read_token(); return tok.t; }
	Token pop() { if (! has_tok) read_token(); has_tok = false; return tok; }
};

struct TreeNode {
	bool empty, leaf, ok;
	TreeNode(): empty(true), leaf(false), ok(false) {}
};

struct Parser {
	Lexer lex;
	Parser(Reader &R): lex(Lexer(R)) {}

	TreeNode tree(int sum) {
		lex.pop(); // must be a PAREN_OPEN

		TreeNode ans;
		if (lex.peek() == INT) {
			ans.empty = false;
			Token tok = lex.pop();

			TreeNode lt = tree(sum - tok.n);
			TreeNode rt = tree(sum - tok.n);

			if (lt.empty && rt.empty) {
				ans.leaf = true;
				if (tok.n == sum) ans.ok = true;
			}
			else
				ans.ok = lt.ok || rt.ok;
		}

		lex.pop();  // must be a PAREN_CLOSE
		return ans;
	}
};
<commit_msg>Small updates<commit_after>//
// Recursive Descent Parser
//

/**
 * Example Grammar:
 *
 *   tree ::= '(' ( | INT <tree> <tree> ) ')'
 */
enum TokenT {
	NONE,
	PAREN_OPEN,
	PAREN_CLOSE,
	INT
};

struct Token {
	TokenT t;
	int n;
};

struct Lexer {
	Reader &rr;
	bool has_tok;
	Token tok;
	Lexer(Reader &R): rr(R), has_tok(false) {}

	void read_token() {
		if (rr.has_next_int())
			tok = (Token) { INT, rr.next_int() };
		else if (rr.has_next()) {
			char c = rr.next_char();
			switch (c) {
			case '(': tok = (Token) { PAREN_OPEN }; break;
			case ')': tok = (Token) { PAREN_CLOSE }; break;
			default: tok = (Token) { NONE };
			}
		}
		else
			tok = (Token) { NONE };

		has_tok = true;
	}

	TokenT peek() { if (! has_tok) read_token(); return tok.t; }
	Token pop() { if (! has_tok) read_token(); has_tok = false; return tok; }
};

// Problem-specific data structure
struct TreeNode {
	bool empty, leaf, ok;
	TreeNode(): empty(true), leaf(false), ok(false) {}
};

struct Parser {
	Lexer lex;
	Parser(Reader &R): lex(Lexer(R)) {}

	TreeNode tree(int sum) {
		lex.pop(); // must be a PAREN_OPEN

		TreeNode ans;
		if (lex.peek() == INT) {
			ans.empty = false;
			Token tok = lex.pop();

			TreeNode lt = tree(sum - tok.n);
			TreeNode rt = tree(sum - tok.n);

			if (lt.empty && rt.empty) {
				ans.leaf = true;
				if (tok.n == sum) ans.ok = true;
			}
			else
				ans.ok = lt.ok || rt.ok;
		}

		lex.pop();  // must be a PAREN_CLOSE
		return ans;
	}
};
<|endoftext|>


<commit_before>//  Natron
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "AnimationButton.h"

#include <QMouseEvent>
#include <QApplication>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDropEvent>
#include <QDrag>

#include "Gui/KnobGui.h"
#include "Engine/Project.h"
#include "Engine/Knob.h"
#include "Global/AppManager.h"

void AnimationButton::mousePressEvent(QMouseEvent* event){
    if (event->button() == Qt::LeftButton) {
        _dragPos = event->pos();
        _dragging = true;
    }
    QPushButton::mousePressEvent(event);
}

void AnimationButton::mouseMoveEvent(QMouseEvent* event){

    if(_dragging){
        // If the left button isn't pressed anymore then return
        if (!(event->buttons() & Qt::LeftButton))
            return;
        // If the distance is too small then return
        if ((event->pos() - _dragPos).manhattanLength() < QApplication::startDragDistance())
            return;

        // initiate Drag

        _knob->onCopyAnimationActionTriggered();
        QDrag* drag = new QDrag(this);
        QMimeData* mimeData = new QMimeData;
        mimeData->setData("Animation", "");
        drag->setMimeData(mimeData);
        #if QT_VERSION < 0x050000
        QPixmap pix = QPixmap::grabWidget(this);
        #else
        QPixmap pix = grab();
        #endif
        drag->setPixmap(pix);

        drag->exec();
    }else{
        QPushButton::mouseMoveEvent(event);
    }
}

void AnimationButton::mouseReleaseEvent(QMouseEvent* event) {
    _dragging = false;
    QPushButton::mouseReleaseEvent(event);
}

void AnimationButton::dragEnterEvent(QDragEnterEvent* event){

    if(event->source() == this){
        return;
    }
    QStringList formats = event->mimeData()->formats();
    if (formats.contains("Animation")) {
        setCursor(Qt::DragCopyCursor);
        event->acceptProposedAction();
    }
}

void AnimationButton::dragLeaveEvent(QDragLeaveEvent* /*event*/){

}

void AnimationButton::dropEvent(QDropEvent* event){
    event->accept();
    QStringList formats = event->mimeData()->formats();
    if (formats.contains("Animation")) {
        _knob->onPasteActionTriggered();
        event->acceptProposedAction();
    }
}

void AnimationButton::dragMoveEvent(QDragMoveEvent* event) {

    QStringList formats = event->mimeData()->formats();
    if (formats.contains("Animation")) {
        event->acceptProposedAction();
    }
}

void AnimationButton::enterEvent(QEvent* /*event*/){
    if (cursor().shape() != Qt::OpenHandCursor) {
        setCursor(Qt::OpenHandCursor);
    }
}

void AnimationButton::leaveEvent(QEvent* /*event*/){
    if (cursor().shape() == Qt::OpenHandCursor) {
        setCursor(Qt::ArrowCursor);
    }
}<commit_msg>More meaningful drag hint to the animation button<commit_after>//  Natron
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "AnimationButton.h"

#include <QMouseEvent>
#include <QApplication>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDropEvent>
#include <QDrag>
#include <QPainter>

#include "Gui/KnobGui.h"
#include "Engine/Project.h"
#include "Engine/Knob.h"
#include "Global/AppManager.h"

void AnimationButton::mousePressEvent(QMouseEvent* event){
    if (event->button() == Qt::LeftButton) {
        _dragPos = event->pos();
        _dragging = true;
    }
    QPushButton::mousePressEvent(event);
}

void AnimationButton::mouseMoveEvent(QMouseEvent* event){

    if(_dragging){
        // If the left button isn't pressed anymore then return
        if (!(event->buttons() & Qt::LeftButton))
            return;
        // If the distance is too small then return
        if ((event->pos() - _dragPos).manhattanLength() < QApplication::startDragDistance())
            return;

        // initiate Drag

        _knob->onCopyAnimationActionTriggered();
        QDrag* drag = new QDrag(this);
        QMimeData* mimeData = new QMimeData;
        mimeData->setData("Animation", "");
        drag->setMimeData(mimeData);

        QFontMetrics fmetrics = fontMetrics();
        QString textFirstLine("Copying animation from:");
        QString textSecondLine(_knob->getKnob()->getDescription().c_str());
        QString textThirdLine("Drag it to another animation button.");

        int textWidth = std::max(std::max(fmetrics.width(textFirstLine), fmetrics.width(textSecondLine)),fmetrics.width(textThirdLine));

        QImage dragImg(textWidth,(fmetrics.height() + 5) * 3,QImage::Format_ARGB32);
        dragImg.fill(QColor(243,137,0));
        QPainter p(&dragImg);
        p.drawText(QPointF(0,dragImg.height() - 2.5), textThirdLine);
        p.drawText(QPointF(0,dragImg.height() - fmetrics.height() - 5), textSecondLine);
        p.drawText(QPointF(0,dragImg.height() - fmetrics.height()*2 - 10), textFirstLine);

        drag->setPixmap(QPixmap::fromImage(dragImg));

        drag->exec();
    }else{
        QPushButton::mouseMoveEvent(event);
    }
}

void AnimationButton::mouseReleaseEvent(QMouseEvent* event) {
    _dragging = false;
    QPushButton::mouseReleaseEvent(event);
}

void AnimationButton::dragEnterEvent(QDragEnterEvent* event){

    if(event->source() == this){
        return;
    }
    QStringList formats = event->mimeData()->formats();
    if (formats.contains("Animation")) {
        setCursor(Qt::DragCopyCursor);
        event->acceptProposedAction();
    }
}

void AnimationButton::dragLeaveEvent(QDragLeaveEvent* /*event*/){

}

void AnimationButton::dropEvent(QDropEvent* event){
    event->accept();
    QStringList formats = event->mimeData()->formats();
    if (formats.contains("Animation")) {
        _knob->onPasteActionTriggered();
        event->acceptProposedAction();
    }
}

void AnimationButton::dragMoveEvent(QDragMoveEvent* event) {

    QStringList formats = event->mimeData()->formats();
    if (formats.contains("Animation")) {
        event->acceptProposedAction();
    }
}

void AnimationButton::enterEvent(QEvent* /*event*/){
    if (cursor().shape() != Qt::OpenHandCursor) {
        setCursor(Qt::OpenHandCursor);
    }
}

void AnimationButton::leaveEvent(QEvent* /*event*/){
    if (cursor().shape() == Qt::OpenHandCursor) {
        setCursor(Qt::ArrowCursor);
    }
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include "arch/x86/predecoder.hh"
#include "base/misc.hh"
#include "base/trace.hh"
#include "sim/host.hh"

namespace X86ISA
{
    void Predecoder::process()
    {
        //This function drives the predecoder state machine.

        //Some sanity checks. You shouldn't try to process more bytes if
        //there aren't any, and you shouldn't overwrite an already
        //predecoder ExtMachInst.
        assert(!outOfBytes);
        assert(!emiIsReady);

        //While there's still something to do...
        while(!emiIsReady && !outOfBytes)
        {
            uint8_t nextByte = getNextByte();
            switch(state)
            {
              case PrefixState:
                state = doPrefixState(nextByte);
                break;
              case OpcodeState:
                state = doOpcodeState(nextByte);
                break;
              case ModRMState:
                state = doModRMState(nextByte);
                break;
              case SIBState:
                state = doSIBState(nextByte);
                break;
              case DisplacementState:
                state = doDisplacementState();
                break;
              case ImmediateState:
                state = doImmediateState();
                break;
              case ErrorState:
                panic("Went to the error state in the predecoder.\n");
              default:
                panic("Unrecognized state! %d\n", state);
            }
        }
    }

    //Either get a prefix and record it in the ExtMachInst, or send the
    //state machine on to get the opcode(s).
    Predecoder::State Predecoder::doPrefixState(uint8_t nextByte)
    {
        uint8_t prefix = Prefixes[nextByte];
        State nextState = PrefixState;
        if(prefix)
            consumeByte();
        switch(prefix)
        {
            //Operand size override prefixes
          case OperandSizeOverride:
            DPRINTF(Predecoder, "Found operand size override prefix.\n");
            break;
          case AddressSizeOverride:
            DPRINTF(Predecoder, "Found address size override prefix.\n");
            break;
            //Segment override prefixes
          case CSOverride:
            DPRINTF(Predecoder, "Found cs segment override.\n");
            break;
          case DSOverride:
            DPRINTF(Predecoder, "Found ds segment override.\n");
            break;
          case ESOverride:
            DPRINTF(Predecoder, "Found es segment override.\n");
            break;
          case FSOverride:
            DPRINTF(Predecoder, "Found fs segment override.\n");
            break;
          case GSOverride:
            DPRINTF(Predecoder, "Found gs segment override.\n");
            break;
          case SSOverride:
            DPRINTF(Predecoder, "Found ss segment override.\n");
            break;
          case Lock:
            DPRINTF(Predecoder, "Found lock prefix.\n");
            break;
          case Rep:
            DPRINTF(Predecoder, "Found rep prefix.\n");
            break;
          case Repne:
            DPRINTF(Predecoder, "Found repne prefix.\n");
            break;
          case RexPrefix:
            DPRINTF(Predecoder, "Found Rex prefix %#x.\n", nextByte);
            emi.rex = nextByte;
            break;
          case 0:
            emi.opcode.num = 0;
            nextState = OpcodeState;
            break;
          default:
            panic("Unrecognized prefix %#x\n", nextByte);
        }
        return nextState;
    }

    //Load all the opcodes (currently up to 2) and then figure out
    //what immediate and/or ModRM is needed.
    Predecoder::State Predecoder::doOpcodeState(uint8_t nextByte)
    {
        State nextState = ErrorState;
        emi.opcode.num++;
        //We can't handle 3+ byte opcodes right now
        assert(emi.opcode.num < 3);
        consumeByte();
        if(emi.opcode.num == 1 && nextByte == 0x0f)
        {
            nextState = OpcodeState;
            DPRINTF(Predecoder, "Found two byte opcode.\n");
            emi.opcode.prefixA = nextByte;
        }
        else if(emi.opcode.num == 2 &&
                (nextByte == 0x0f ||
                 (nextByte & 0xf8) == 0x38))
        {
            panic("Three byte opcodes aren't yet supported!\n");
            nextState = OpcodeState;
            DPRINTF(Predecoder, "Found three byte opcode.\n");
            emi.opcode.prefixB = nextByte;
        }
        else
        {
            DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
            emi.opcode.op = nextByte;

            //Prepare for any immediate/displacement we might need
            immediateCollected = 0;
            emi.immediate = 0;
            displacementCollected = 0;
            emi.displacement = 0;

            //Figure out how big of an immediate we'll retreive based
            //on the opcode.
            int immType = ImmediateType[
                emi.opcode.num - 1][nextByte];
            if(0) //16 bit mode
                immediateSize = ImmediateTypeToSize[0][immType];
            else if(!(emi.rex & 0x4)) //32 bit mode
                immediateSize = ImmediateTypeToSize[1][immType];
            else //64 bit mode
                immediateSize = ImmediateTypeToSize[2][immType];

            //Determine what to expect next
            if (UsesModRM[emi.opcode.num - 1][nextByte]) {
                nextState = ModRMState;
            } else if(immediateSize) {
                nextState = ImmediateState;
            } else {
                emiIsReady = true;
                nextState = PrefixState;
            }
        }
        return nextState;
    }

    //Get the ModRM byte and determine what displacement, if any, there is.
    //Also determine whether or not to get the SIB byte, displacement, or
    //immediate next.
    Predecoder::State Predecoder::doModRMState(uint8_t nextByte)
    {
        State nextState = ErrorState;
        emi.modRM = nextByte;
        DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte);
        if (0) {//FIXME in 16 bit mode
            //figure out 16 bit displacement size
            if(nextByte & 0xC7 == 0x06 ||
                    nextByte & 0xC0 == 0x80)
                displacementSize = 2;
            else if(nextByte & 0xC0 == 0x40)
                displacementSize = 1;
            else
                displacementSize = 0;
        } else {
            //figure out 32/64 bit displacement size
            if(nextByte & 0xC7 == 0x05 ||
                    nextByte & 0xC0 == 0x80)
                displacementSize = 4;
            else if(nextByte & 0xC0 == 0x40)
                displacementSize = 2;
            else
                displacementSize = 0;
        }
        //If there's an SIB, get that next.
        //There is no SIB in 16 bit mode.
        if(nextByte & 0x7 == 4 &&
                nextByte & 0xC0 != 0xC0) {
                // && in 32/64 bit mode)
            nextState = SIBState;
        } else if(displacementSize) {
            nextState = DisplacementState;
        } else if(immediateSize) {
            nextState = ImmediateState;
        } else {
            emiIsReady = true;
            nextState = PrefixState;
        }
        //The ModRM byte is consumed no matter what
        consumeByte();
        return nextState;
    }

    //Get the SIB byte. We don't do anything with it at this point, other
    //than storing it in the ExtMachInst. Determine if we need to get a
    //displacement or immediate next.
    Predecoder::State Predecoder::doSIBState(uint8_t nextByte)
    {
        State nextState = ErrorState;
        emi.sib = nextByte;
        DPRINTF(Predecoder, "Found SIB byte %#x.\n", nextByte);
        consumeByte();
        if(displacementSize) {
            nextState = DisplacementState;
        } else if(immediateSize) {
            nextState = ImmediateState;
        } else {
            emiIsReady = true;
            nextState = PrefixState;
        }
        return nextState;
    }

    //Gather up the displacement, or at least as much of it
    //as we can get.
    Predecoder::State Predecoder::doDisplacementState()
    {
        State nextState = ErrorState;

        getImmediate(displacementCollected,
                emi.displacement,
                displacementSize);

        DPRINTF(Predecoder, "Collecting %d byte displacement, got %d bytes.\n",
                displacementSize, displacementCollected);

        if(displacementSize == displacementCollected) {
            //Sign extend the displacement
            switch(displacementSize)
            {
              case 1:
                emi.displacement = sext<8>(emi.displacement);
                break;
              case 2:
                emi.displacement = sext<16>(emi.displacement);
                break;
              case 4:
                emi.displacement = sext<32>(emi.displacement);
                break;
              default:
                panic("Undefined displacement size!\n");
            }
            DPRINTF(Predecoder, "Collected displacement %#x.\n",
                    emi.displacement);
            if(immediateSize) {
                nextState = ImmediateState;
            } else {
                emiIsReady = true;
                nextState = PrefixState;
            }
        }
        else
            nextState = DisplacementState;
        return nextState;
    }

    //Gather up the immediate, or at least as much of it
    //as we can get
    Predecoder::State Predecoder::doImmediateState()
    {
        State nextState = ErrorState;

        getImmediate(immediateCollected,
                emi.immediate,
                immediateSize);

        DPRINTF(Predecoder, "Collecting %d byte immediate, got %d bytes.\n",
                immediateSize, immediateCollected);

        if(immediateSize == immediateCollected)
        {
            DPRINTF(Predecoder, "Collected immediate %#x.\n",
                    emi.immediate);
            emiIsReady = true;
            nextState = PrefixState;
        }
        else
            nextState = ImmediateState;
        return nextState;
    }
}
<commit_msg>Zero out ModRM if the byte isn't there, and fix some displacement size stuff.<commit_after>/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include "arch/x86/predecoder.hh"
#include "base/misc.hh"
#include "base/trace.hh"
#include "sim/host.hh"

namespace X86ISA
{
    void Predecoder::process()
    {
        //This function drives the predecoder state machine.

        //Some sanity checks. You shouldn't try to process more bytes if
        //there aren't any, and you shouldn't overwrite an already
        //predecoder ExtMachInst.
        assert(!outOfBytes);
        assert(!emiIsReady);

        //While there's still something to do...
        while(!emiIsReady && !outOfBytes)
        {
            uint8_t nextByte = getNextByte();
            switch(state)
            {
              case PrefixState:
                state = doPrefixState(nextByte);
                break;
              case OpcodeState:
                state = doOpcodeState(nextByte);
                break;
              case ModRMState:
                state = doModRMState(nextByte);
                break;
              case SIBState:
                state = doSIBState(nextByte);
                break;
              case DisplacementState:
                state = doDisplacementState();
                break;
              case ImmediateState:
                state = doImmediateState();
                break;
              case ErrorState:
                panic("Went to the error state in the predecoder.\n");
              default:
                panic("Unrecognized state! %d\n", state);
            }
        }
    }

    //Either get a prefix and record it in the ExtMachInst, or send the
    //state machine on to get the opcode(s).
    Predecoder::State Predecoder::doPrefixState(uint8_t nextByte)
    {
        uint8_t prefix = Prefixes[nextByte];
        State nextState = PrefixState;
        if(prefix)
            consumeByte();
        switch(prefix)
        {
            //Operand size override prefixes
          case OperandSizeOverride:
            DPRINTF(Predecoder, "Found operand size override prefix.\n");
            break;
          case AddressSizeOverride:
            DPRINTF(Predecoder, "Found address size override prefix.\n");
            break;
            //Segment override prefixes
          case CSOverride:
            DPRINTF(Predecoder, "Found cs segment override.\n");
            break;
          case DSOverride:
            DPRINTF(Predecoder, "Found ds segment override.\n");
            break;
          case ESOverride:
            DPRINTF(Predecoder, "Found es segment override.\n");
            break;
          case FSOverride:
            DPRINTF(Predecoder, "Found fs segment override.\n");
            break;
          case GSOverride:
            DPRINTF(Predecoder, "Found gs segment override.\n");
            break;
          case SSOverride:
            DPRINTF(Predecoder, "Found ss segment override.\n");
            break;
          case Lock:
            DPRINTF(Predecoder, "Found lock prefix.\n");
            break;
          case Rep:
            DPRINTF(Predecoder, "Found rep prefix.\n");
            break;
          case Repne:
            DPRINTF(Predecoder, "Found repne prefix.\n");
            break;
          case RexPrefix:
            DPRINTF(Predecoder, "Found Rex prefix %#x.\n", nextByte);
            emi.rex = nextByte;
            break;
          case 0:
            emi.opcode.num = 0;
            nextState = OpcodeState;
            break;
          default:
            panic("Unrecognized prefix %#x\n", nextByte);
        }
        return nextState;
    }

    //Load all the opcodes (currently up to 2) and then figure out
    //what immediate and/or ModRM is needed.
    Predecoder::State Predecoder::doOpcodeState(uint8_t nextByte)
    {
        State nextState = ErrorState;
        emi.opcode.num++;
        //We can't handle 3+ byte opcodes right now
        assert(emi.opcode.num < 3);
        consumeByte();
        if(emi.opcode.num == 1 && nextByte == 0x0f)
        {
            nextState = OpcodeState;
            DPRINTF(Predecoder, "Found two byte opcode.\n");
            emi.opcode.prefixA = nextByte;
        }
        else if(emi.opcode.num == 2 &&
                (nextByte == 0x0f ||
                 (nextByte & 0xf8) == 0x38))
        {
            panic("Three byte opcodes aren't yet supported!\n");
            nextState = OpcodeState;
            DPRINTF(Predecoder, "Found three byte opcode.\n");
            emi.opcode.prefixB = nextByte;
        }
        else
        {
            DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
            emi.opcode.op = nextByte;

            //Prepare for any immediate/displacement we might need
            immediateCollected = 0;
            emi.immediate = 0;
            displacementCollected = 0;
            emi.displacement = 0;

            //Figure out how big of an immediate we'll retreive based
            //on the opcode.
            int immType = ImmediateType[
                emi.opcode.num - 1][nextByte];
            if(0) //16 bit mode
                immediateSize = ImmediateTypeToSize[0][immType];
            else if(!(emi.rex & 0x4)) //32 bit mode
                immediateSize = ImmediateTypeToSize[1][immType];
            else //64 bit mode
                immediateSize = ImmediateTypeToSize[2][immType];

            //Determine what to expect next
            if (UsesModRM[emi.opcode.num - 1][nextByte]) {
                nextState = ModRMState;
            } else {
                //If there's no modRM byte, set it to 0 so we can detect
                //that later.
                emi.modRM = 0;
                if(immediateSize) {
                    nextState = ImmediateState;
                } else {
                    emiIsReady = true;
                    nextState = PrefixState;
                }
            }
        }
        return nextState;
    }

    //Get the ModRM byte and determine what displacement, if any, there is.
    //Also determine whether or not to get the SIB byte, displacement, or
    //immediate next.
    Predecoder::State Predecoder::doModRMState(uint8_t nextByte)
    {
        State nextState = ErrorState;
        emi.modRM = nextByte;
        DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte);
        if (0) {//FIXME in 16 bit mode
            //figure out 16 bit displacement size
            if(nextByte & 0xC7 == 0x06 ||
                    nextByte & 0xC0 == 0x80)
                displacementSize = 2;
            else if(nextByte & 0xC0 == 0x40)
                displacementSize = 1;
            else
                displacementSize = 0;
        } else {
            //figure out 32/64 bit displacement size
            if(nextByte & 0xC6 == 0x04 ||
                    nextByte & 0xC0 == 0x80)
                displacementSize = 4;
            else if(nextByte & 0xC0 == 0x40)
                displacementSize = 1;
            else
                displacementSize = 0;
        }
        //If there's an SIB, get that next.
        //There is no SIB in 16 bit mode.
        if(nextByte & 0x7 == 4 &&
                nextByte & 0xC0 != 0xC0) {
                // && in 32/64 bit mode)
            nextState = SIBState;
        } else if(displacementSize) {
            nextState = DisplacementState;
        } else if(immediateSize) {
            nextState = ImmediateState;
        } else {
            emiIsReady = true;
            nextState = PrefixState;
        }
        //The ModRM byte is consumed no matter what
        consumeByte();
        return nextState;
    }

    //Get the SIB byte. We don't do anything with it at this point, other
    //than storing it in the ExtMachInst. Determine if we need to get a
    //displacement or immediate next.
    Predecoder::State Predecoder::doSIBState(uint8_t nextByte)
    {
        State nextState = ErrorState;
        emi.sib = nextByte;
        DPRINTF(Predecoder, "Found SIB byte %#x.\n", nextByte);
        consumeByte();
        if(displacementSize) {
            nextState = DisplacementState;
        } else if(immediateSize) {
            nextState = ImmediateState;
        } else {
            emiIsReady = true;
            nextState = PrefixState;
        }
        return nextState;
    }

    //Gather up the displacement, or at least as much of it
    //as we can get.
    Predecoder::State Predecoder::doDisplacementState()
    {
        State nextState = ErrorState;

        getImmediate(displacementCollected,
                emi.displacement,
                displacementSize);

        DPRINTF(Predecoder, "Collecting %d byte displacement, got %d bytes.\n",
                displacementSize, displacementCollected);

        if(displacementSize == displacementCollected) {
            //Sign extend the displacement
            switch(displacementSize)
            {
              case 1:
                emi.displacement = sext<8>(emi.displacement);
                break;
              case 2:
                emi.displacement = sext<16>(emi.displacement);
                break;
              case 4:
                emi.displacement = sext<32>(emi.displacement);
                break;
              default:
                panic("Undefined displacement size!\n");
            }
            DPRINTF(Predecoder, "Collected displacement %#x.\n",
                    emi.displacement);
            if(immediateSize) {
                nextState = ImmediateState;
            } else {
                emiIsReady = true;
                nextState = PrefixState;
            }
        }
        else
            nextState = DisplacementState;
        return nextState;
    }

    //Gather up the immediate, or at least as much of it
    //as we can get
    Predecoder::State Predecoder::doImmediateState()
    {
        State nextState = ErrorState;

        getImmediate(immediateCollected,
                emi.immediate,
                immediateSize);

        DPRINTF(Predecoder, "Collecting %d byte immediate, got %d bytes.\n",
                immediateSize, immediateCollected);

        if(immediateSize == immediateCollected)
        {
            DPRINTF(Predecoder, "Collected immediate %#x.\n",
                    emi.immediate);
            emiIsReady = true;
            nextState = PrefixState;
        }
        else
            nextState = ImmediateState;
        return nextState;
    }
}
<|endoftext|>


<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
// Copyright 2010 Dennis Nienhüser <earthwings@gentoo.org>

#include "MarbleRunnerManager.h"

#include "MarblePlacemarkModel.h"
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "Planet.h"
#include "GeoDataPlacemark.h"
#include "PluginManager.h"
#include "RunnerPlugin.h"
#include "RunnerTask.h"
#include "routing/RouteRequest.h"
#include "routing/RoutingProfilesModel.h"

#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QVector>
#include <QtCore/QThreadPool>
#include <QtCore/QTimer>

namespace Marble
{

class MarbleModel;

class MarbleRunnerManagerPrivate
{
public:
    MarbleRunnerManager* q;
    QString m_lastSearchTerm;
    QMutex m_modelMutex;
    MarbleModel * m_marbleModel;
    MarblePlacemarkModel *m_model;
    QVector<GeoDataPlacemark*> m_placemarkContainer;
    QVector<GeoDataDocument*> m_routingResult;
    QList<GeoDataCoordinates> m_reverseGeocodingResults;
    RouteRequest* m_routeRequest;
    bool m_workOffline;
    PluginManager* m_pluginManager;

    MarbleRunnerManagerPrivate( MarbleRunnerManager* parent, PluginManager* pluginManager );

    ~MarbleRunnerManagerPrivate();

    QList<RunnerPlugin*> plugins( RunnerPlugin::Capability capability );

    QList<RunnerTask*> m_searchTasks;
    QList<RunnerTask*> m_routingTasks;

    void cleanupSearchTask( RunnerTask* task );

    void cleanupRoutingTask( RunnerTask* task );
};

MarbleRunnerManagerPrivate::MarbleRunnerManagerPrivate( MarbleRunnerManager* parent, PluginManager* pluginManager ) :
        q( parent ),
        m_marbleModel( 0 ),
        m_model( new MarblePlacemarkModel ),
        m_routeRequest( 0 ),
        m_workOffline( false ),
        m_pluginManager( pluginManager )
{
    m_model->setPlacemarkContainer( &m_placemarkContainer );
    qRegisterMetaType<GeoDataPlacemark>( "GeoDataPlacemark" );
    qRegisterMetaType<GeoDataCoordinates>( "GeoDataCoordinates" );
    qRegisterMetaType<QVector<GeoDataPlacemark*> >( "QVector<GeoDataPlacemark*>" );
}

MarbleRunnerManagerPrivate::~MarbleRunnerManagerPrivate()
{
    delete m_model;
}

QList<RunnerPlugin*> MarbleRunnerManagerPrivate::plugins( RunnerPlugin::Capability capability )
{
    QList<RunnerPlugin*> result;
    QList<RunnerPlugin*> plugins = m_pluginManager->runnerPlugins();
    foreach( RunnerPlugin* plugin, plugins ) {
        if ( !plugin->supports( capability ) ) {
            continue;
        }

        if ( ( m_workOffline && !plugin->canWorkOffline() ) ) {
            continue;
        }

        if ( !plugin->canWork( capability ) ) {
            continue;
        }

        if ( m_marbleModel && !plugin->supportsCelestialBody( m_marbleModel->planet()->id() ) )
        {
            continue;
        }

        result << plugin;
    }

    return result;
}

void MarbleRunnerManagerPrivate::cleanupSearchTask( RunnerTask* task )
{
    m_searchTasks.removeAll( task );

    if ( m_searchTasks.isEmpty() ) {
        emit q->searchFinished( m_lastSearchTerm );
    }
}

void MarbleRunnerManagerPrivate::cleanupRoutingTask( RunnerTask* task )
{
    m_routingTasks.removeAll( task );

    if ( m_routingTasks.isEmpty() && m_routingResult.isEmpty() ) {
        emit q->routeRetrieved( 0 );
    }
}

MarbleRunnerManager::MarbleRunnerManager( PluginManager* pluginManager, QObject *parent )
    : QObject( parent ), d( new MarbleRunnerManagerPrivate( this, pluginManager ) )
{
    if ( QThreadPool::globalInstance()->maxThreadCount() < 4 ) {
        QThreadPool::globalInstance()->setMaxThreadCount( 4 );
    }
}

MarbleRunnerManager::~MarbleRunnerManager()
{
    delete d;
}

void MarbleRunnerManager::reverseGeocoding( const GeoDataCoordinates &coordinates )
{
    d->m_reverseGeocodingResults.removeAll( coordinates );
    QList<RunnerPlugin*> plugins = d->plugins( RunnerPlugin::ReverseGeocoding );
    foreach( RunnerPlugin* plugin, plugins ) {
        MarbleAbstractRunner* runner = plugin->newRunner();
        runner->setParent( this );
        connect( runner, SIGNAL( reverseGeocodingFinished( GeoDataCoordinates, GeoDataPlacemark ) ),
                 this, SLOT( addReverseGeocodingResult( GeoDataCoordinates, GeoDataPlacemark ) ) );
        runner->setModel( d->m_marbleModel );
        QThreadPool::globalInstance()->start( new ReverseGeocodingTask( runner, coordinates ) );
    }

    if ( plugins.isEmpty() ) {
        emit reverseGeocodingFinished( coordinates, GeoDataPlacemark() );
    }
}

void MarbleRunnerManager::findPlacemarks( const QString &searchTerm )
{
    if ( searchTerm == d->m_lastSearchTerm ) {
      emit searchFinished( searchTerm );
      emit searchResultChanged( d->m_model );
      return;
    }

    d->m_lastSearchTerm = searchTerm;

    d->m_searchTasks.clear();

    d->m_modelMutex.lock();
    d->m_model->removePlacemarks( "MarbleRunnerManager", 0, d->m_placemarkContainer.size() );
    qDeleteAll( d->m_placemarkContainer );
    d->m_placemarkContainer.clear();
    d->m_modelMutex.unlock();
    emit searchResultChanged( d->m_model );

    QList<RunnerPlugin*> plugins = d->plugins( RunnerPlugin::Search );
    foreach( RunnerPlugin* plugin, plugins ) {
        MarbleAbstractRunner* runner = plugin->newRunner();
        runner->setParent( this );
        connect( runner, SIGNAL( searchFinished( QVector<GeoDataPlacemark*> ) ),
                 this, SLOT( addSearchResult( QVector<GeoDataPlacemark*> ) ) );
        runner->setModel( d->m_marbleModel );
        SearchTask* task = new SearchTask( runner, searchTerm );
        connect( task, SIGNAL( finished( RunnerTask* ) ), this, SLOT( cleanupSearchTask( RunnerTask* ) ) );
        d->m_searchTasks << task;
        QThreadPool::globalInstance()->start( task );
    }
}

void MarbleRunnerManager::addSearchResult( QVector<GeoDataPlacemark*> result )
{
    mDebug() << "Runner reports" << result.size() << " search results";
    if( result.isEmpty() )
        return;

    d->m_modelMutex.lock();
    int start = d->m_placemarkContainer.size();
    d->m_placemarkContainer << result;
    d->m_model->addPlacemarks( start, result.size() );
    d->m_modelMutex.unlock();
    emit searchResultChanged( d->m_model );
}

void MarbleRunnerManager::setModel( MarbleModel * model )
{
    // TODO: Terminate runners which are making use of the map.
    d->m_marbleModel = model;
}

void MarbleRunnerManager::setWorkOffline( bool offline )
{
    d->m_workOffline = offline;
}

void MarbleRunnerManager::addReverseGeocodingResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark )
{
    if ( !d->m_reverseGeocodingResults.contains( coordinates ) && !placemark.address().isEmpty() ) {
        d->m_reverseGeocodingResults.push_back( coordinates );
        emit reverseGeocodingFinished( coordinates, placemark );
    }
}

void MarbleRunnerManager::retrieveRoute( RouteRequest *request )
{
    RoutingProfile profile = request->routingProfile();

    d->m_routingTasks.clear();
    d->m_routingResult.clear();

    d->m_routeRequest = request;
    QList<RunnerPlugin*> plugins = d->plugins( RunnerPlugin::Routing );
    bool started = false;
    foreach( RunnerPlugin* plugin, plugins ) {
        if ( !profile.pluginSettings().contains( plugin->nameId() ) ) {
            continue;
        }

        started = true;
        MarbleAbstractRunner* runner = plugin->newRunner();
        runner->setParent( this );
        connect( runner, SIGNAL( routeCalculated( GeoDataDocument* ) ),
                 this, SLOT( addRoutingResult( GeoDataDocument* ) ) );
        runner->setModel( d->m_marbleModel );
        RoutingTask* task = new RoutingTask( runner, request );
        d->m_routingTasks << task;
        connect( task, SIGNAL( finished( RunnerTask* ) ), this, SLOT( cleanupRoutingTask( RunnerTask* ) ) );
        QThreadPool::globalInstance()->start( task );
    }

    if ( !started ) {
        mDebug() << "No routing plugins found, cannot retrieve a route";
        d->cleanupRoutingTask( 0 );
    }
}

void MarbleRunnerManager::addRoutingResult( GeoDataDocument* route )
{
    if ( route ) {
        d->m_routingResult.push_back( route );
        emit routeRetrieved( route );
    }
}

}

#include "MarbleRunnerManager.moc"
<commit_msg>Run all backends with default settings when no profile has been set.<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
// Copyright 2010 Dennis Nienhüser <earthwings@gentoo.org>

#include "MarbleRunnerManager.h"

#include "MarblePlacemarkModel.h"
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "Planet.h"
#include "GeoDataPlacemark.h"
#include "PluginManager.h"
#include "RunnerPlugin.h"
#include "RunnerTask.h"
#include "routing/RouteRequest.h"
#include "routing/RoutingProfilesModel.h"

#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QVector>
#include <QtCore/QThreadPool>
#include <QtCore/QTimer>

namespace Marble
{

class MarbleModel;

class MarbleRunnerManagerPrivate
{
public:
    MarbleRunnerManager* q;
    QString m_lastSearchTerm;
    QMutex m_modelMutex;
    MarbleModel * m_marbleModel;
    MarblePlacemarkModel *m_model;
    QVector<GeoDataPlacemark*> m_placemarkContainer;
    QVector<GeoDataDocument*> m_routingResult;
    QList<GeoDataCoordinates> m_reverseGeocodingResults;
    RouteRequest* m_routeRequest;
    bool m_workOffline;
    PluginManager* m_pluginManager;

    MarbleRunnerManagerPrivate( MarbleRunnerManager* parent, PluginManager* pluginManager );

    ~MarbleRunnerManagerPrivate();

    QList<RunnerPlugin*> plugins( RunnerPlugin::Capability capability );

    QList<RunnerTask*> m_searchTasks;
    QList<RunnerTask*> m_routingTasks;

    void cleanupSearchTask( RunnerTask* task );

    void cleanupRoutingTask( RunnerTask* task );
};

MarbleRunnerManagerPrivate::MarbleRunnerManagerPrivate( MarbleRunnerManager* parent, PluginManager* pluginManager ) :
        q( parent ),
        m_marbleModel( 0 ),
        m_model( new MarblePlacemarkModel ),
        m_routeRequest( 0 ),
        m_workOffline( false ),
        m_pluginManager( pluginManager )
{
    m_model->setPlacemarkContainer( &m_placemarkContainer );
    qRegisterMetaType<GeoDataPlacemark>( "GeoDataPlacemark" );
    qRegisterMetaType<GeoDataCoordinates>( "GeoDataCoordinates" );
    qRegisterMetaType<QVector<GeoDataPlacemark*> >( "QVector<GeoDataPlacemark*>" );
}

MarbleRunnerManagerPrivate::~MarbleRunnerManagerPrivate()
{
    delete m_model;
}

QList<RunnerPlugin*> MarbleRunnerManagerPrivate::plugins( RunnerPlugin::Capability capability )
{
    QList<RunnerPlugin*> result;
    QList<RunnerPlugin*> plugins = m_pluginManager->runnerPlugins();
    foreach( RunnerPlugin* plugin, plugins ) {
        if ( !plugin->supports( capability ) ) {
            continue;
        }

        if ( ( m_workOffline && !plugin->canWorkOffline() ) ) {
            continue;
        }

        if ( !plugin->canWork( capability ) ) {
            continue;
        }

        if ( m_marbleModel && !plugin->supportsCelestialBody( m_marbleModel->planet()->id() ) )
        {
            continue;
        }

        result << plugin;
    }

    return result;
}

void MarbleRunnerManagerPrivate::cleanupSearchTask( RunnerTask* task )
{
    m_searchTasks.removeAll( task );

    if ( m_searchTasks.isEmpty() ) {
        emit q->searchFinished( m_lastSearchTerm );
    }
}

void MarbleRunnerManagerPrivate::cleanupRoutingTask( RunnerTask* task )
{
    m_routingTasks.removeAll( task );

    if ( m_routingTasks.isEmpty() && m_routingResult.isEmpty() ) {
        emit q->routeRetrieved( 0 );
    }
}

MarbleRunnerManager::MarbleRunnerManager( PluginManager* pluginManager, QObject *parent )
    : QObject( parent ), d( new MarbleRunnerManagerPrivate( this, pluginManager ) )
{
    if ( QThreadPool::globalInstance()->maxThreadCount() < 4 ) {
        QThreadPool::globalInstance()->setMaxThreadCount( 4 );
    }
}

MarbleRunnerManager::~MarbleRunnerManager()
{
    delete d;
}

void MarbleRunnerManager::reverseGeocoding( const GeoDataCoordinates &coordinates )
{
    d->m_reverseGeocodingResults.removeAll( coordinates );
    QList<RunnerPlugin*> plugins = d->plugins( RunnerPlugin::ReverseGeocoding );
    foreach( RunnerPlugin* plugin, plugins ) {
        MarbleAbstractRunner* runner = plugin->newRunner();
        runner->setParent( this );
        connect( runner, SIGNAL( reverseGeocodingFinished( GeoDataCoordinates, GeoDataPlacemark ) ),
                 this, SLOT( addReverseGeocodingResult( GeoDataCoordinates, GeoDataPlacemark ) ) );
        runner->setModel( d->m_marbleModel );
        QThreadPool::globalInstance()->start( new ReverseGeocodingTask( runner, coordinates ) );
    }

    if ( plugins.isEmpty() ) {
        emit reverseGeocodingFinished( coordinates, GeoDataPlacemark() );
    }
}

void MarbleRunnerManager::findPlacemarks( const QString &searchTerm )
{
    if ( searchTerm == d->m_lastSearchTerm ) {
      emit searchFinished( searchTerm );
      emit searchResultChanged( d->m_model );
      return;
    }

    d->m_lastSearchTerm = searchTerm;

    d->m_searchTasks.clear();

    d->m_modelMutex.lock();
    d->m_model->removePlacemarks( "MarbleRunnerManager", 0, d->m_placemarkContainer.size() );
    qDeleteAll( d->m_placemarkContainer );
    d->m_placemarkContainer.clear();
    d->m_modelMutex.unlock();
    emit searchResultChanged( d->m_model );

    QList<RunnerPlugin*> plugins = d->plugins( RunnerPlugin::Search );
    foreach( RunnerPlugin* plugin, plugins ) {
        MarbleAbstractRunner* runner = plugin->newRunner();
        runner->setParent( this );
        connect( runner, SIGNAL( searchFinished( QVector<GeoDataPlacemark*> ) ),
                 this, SLOT( addSearchResult( QVector<GeoDataPlacemark*> ) ) );
        runner->setModel( d->m_marbleModel );
        SearchTask* task = new SearchTask( runner, searchTerm );
        connect( task, SIGNAL( finished( RunnerTask* ) ), this, SLOT( cleanupSearchTask( RunnerTask* ) ) );
        d->m_searchTasks << task;
        QThreadPool::globalInstance()->start( task );
    }
}

void MarbleRunnerManager::addSearchResult( QVector<GeoDataPlacemark*> result )
{
    mDebug() << "Runner reports" << result.size() << " search results";
    if( result.isEmpty() )
        return;

    d->m_modelMutex.lock();
    int start = d->m_placemarkContainer.size();
    d->m_placemarkContainer << result;
    d->m_model->addPlacemarks( start, result.size() );
    d->m_modelMutex.unlock();
    emit searchResultChanged( d->m_model );
}

void MarbleRunnerManager::setModel( MarbleModel * model )
{
    // TODO: Terminate runners which are making use of the map.
    d->m_marbleModel = model;
}

void MarbleRunnerManager::setWorkOffline( bool offline )
{
    d->m_workOffline = offline;
}

void MarbleRunnerManager::addReverseGeocodingResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark )
{
    if ( !d->m_reverseGeocodingResults.contains( coordinates ) && !placemark.address().isEmpty() ) {
        d->m_reverseGeocodingResults.push_back( coordinates );
        emit reverseGeocodingFinished( coordinates, placemark );
    }
}

void MarbleRunnerManager::retrieveRoute( RouteRequest *request )
{
    RoutingProfile profile = request->routingProfile();

    d->m_routingTasks.clear();
    d->m_routingResult.clear();

    d->m_routeRequest = request;
    QList<RunnerPlugin*> plugins = d->plugins( RunnerPlugin::Routing );
    bool started = false;
    foreach( RunnerPlugin* plugin, plugins ) {
        if ( !profile.name().isEmpty() && !profile.pluginSettings().contains( plugin->nameId() ) ) {
            continue;
        }

        started = true;
        MarbleAbstractRunner* runner = plugin->newRunner();
        runner->setParent( this );
        connect( runner, SIGNAL( routeCalculated( GeoDataDocument* ) ),
                 this, SLOT( addRoutingResult( GeoDataDocument* ) ) );
        runner->setModel( d->m_marbleModel );
        RoutingTask* task = new RoutingTask( runner, request );
        d->m_routingTasks << task;
        connect( task, SIGNAL( finished( RunnerTask* ) ), this, SLOT( cleanupRoutingTask( RunnerTask* ) ) );
        QThreadPool::globalInstance()->start( task );
    }

    if ( !started ) {
        mDebug() << "No routing plugins found, cannot retrieve a route";
        d->cleanupRoutingTask( 0 );
    }
}

void MarbleRunnerManager::addRoutingResult( GeoDataDocument* route )
{
    if ( route ) {
        d->m_routingResult.push_back( route );
        emit routeRetrieved( route );
    }
}

}

#include "MarbleRunnerManager.moc"
<|endoftext|>


<commit_before>#include <iostream>

using namespace std;

int main(int argc, char *argv[]) {
  return -1;
}
<commit_msg>read edges into memory, assign node ids<commit_after>#include <cstdio>
#include <sys/mman.h>
#include <fcntl.h>
#include <iostream>
#include <string>
#include <sys/stat.h>
#include <unistd.h>
#include <unordered_map>
#include <vector>

#define DEBUG             1
#define NODE_NAME_SIZE    20
#define TYPE_NAME_SIZE    1
#define DELIMITER         ' '

using namespace std;

void panic(string message) {
  cout << message << endl;
  exit(-1);
}

int read_edges(string filename,
               vector<pair<pair<int,int>,string>>& edges,
               unordered_map<string,int>& node_id) {
  int nverts = 0;
  int fd, i, j;
  struct stat fstatbuf;
  char *data;
  char src_name[NODE_NAME_SIZE];
  char dst_name[NODE_NAME_SIZE];
  char typ_name[NODE_NAME_SIZE];
  unordered_map<string,int>::iterator it;

  if (DEBUG)
    cout << "Reading edges from: " << filename << endl;

  fd = open(filename.c_str(), O_RDONLY);
  fstat(fd, &fstatbuf);

  // memory map the file
  data = (char*) mmap(NULL, fstatbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  if (data < 0) { // mmap failed
    panic("mmap'ing graph file failed");
    close(fd);
  }

  // read edges from the file
  i = 0;
  while (i < fstatbuf.st_size) {
    // field 1: source name
    j = 0;
    while (data[i] != DELIMITER) {
      src_name[j] = data[i];
      i++;
      j++;
    }
    src_name[j] = '\0';

    i++; // skip delimiter

    // field 2: destination name
    j = 0;
    while (data[i] != DELIMITER) {
      dst_name[j] = data[i];
      i++;
      j++;
    }
    dst_name[j] = '\0';

    i++; // skip delimiter

    // field 3: type name
    j = 0;
    while (data[i] != '\n') {
      typ_name[j] = data[i];
      i++;
      j++;
    }
    typ_name[j] = '\0';

    i++; // skip newline

    if (DEBUG)
      cout << "src: " << src_name
           << " dest: " << dst_name
           << " type: " << typ_name << endl;

    string u = string(src_name);
    string v = string(dst_name);
    string t = string(typ_name);

    // create a node_id for the source
    it = node_id.find(u);
    if (it == node_id.end()) { // unseen node
      node_id[u] = nverts; // allocate new id
      nverts++;
    }

    // create a node_id for the destination
    it = node_id.find(v);
    if (it == node_id.end()) { // unseen node
      node_id[v] = nverts; // allocate new id
      nverts++;
    }

    // add an edge to memory
    edges.push_back(make_pair(make_pair(node_id[u], node_id[v]), t));
  }

  close(fd);

  return nverts;
}

void print_usage() {
  cout << "USAGE: ./swoosh <GRAPH FILE>\n";
}

int main(int argc, char *argv[]) {
  unordered_map<string,int> node_id;        // map memory address to an integer
  vector<pair<pair<int,int>,string>> edges;              // edge list
  vector<vector<pair<string,string>>> G;    // adjacency list w/ edge types

  if (argc != 2) {
    print_usage();
    return -1;
  }

  read_edges(argv[1], edges, node_id);

  if (DEBUG) {
    for (unordered_map<string,int>::iterator it = node_id.begin();
         it != node_id.end();
         it++) {
      cout << "Key: " << it->first << " Value: " << it->second << endl;
    }

    for (uint32_t i = 0; i < edges.size(); i++) {
      cout << edges[i].first.first << " " << edges[i].first.second
           << " " << edges[i].second << endl;
    }
  }

  return 0;
}
<|endoftext|>


<commit_before><commit_msg>dowang fix init error<commit_after><|endoftext|>