<commit_before>/*

    Copyright Eli Dupree and Isaac Dupree, 2011, 2012

    This file is part of Lasercake.

    Lasercake is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Lasercake is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Lasercake.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "world.hpp"
#include "data_structures/borrowed_bitset.hpp"
#include "object_and_tile_iteration.hpp"
#include "data_structures/polygon_collision_detection.hpp"

const int SUN_AREA_SIZE = 5000;

struct sunlight_visitor {
  sunlight_visitor(world *w, vector3<fine_scalar> sun_direction): packets(SUN_AREA_SIZE*SUN_AREA_SIZE),w(w),sun_direction(sun_direction) {}
  borrowed_bitset packets;
  octant_number octant()const { return vector_octant(sun_direction); }
  octant_number octant_; //e.g. from vector_octant()

  int do_poly(convex_polyhedron const& p) {
    int result = 0;
    int max_x, max_y, min_x, min_y;
    bool any = false;
    for (vector3<fine_scalar> const& v : p.vertices()) {
      vector3<fine_scalar> projected_vertex = v;
      projected_vertex -= world_center_fine_coords;
      /*projected_vertex[X] -= projected_vertex(Z) * sun_direction(X) / sun_direction(Z);
      projected_vertex[Y] -= projected_vertex(Z) * sun_direction(Y) / sun_direction(Z);
      projected_vertex[Z] = 0;

      projected_vertex[X] = (projected_vertex(X) * 10 / tile_width) + (SUN_AREA_SIZE / 2);
      projected_vertex[Y] = (projected_vertex(Y) * 10 / tile_width) + (SUN_AREA_SIZE / 2);*/
      projected_vertex[X] = ((projected_vertex(X) * sun_direction(Z) - projected_vertex(Z) * sun_direction(X)) * 10 / (tile_width * sun_direction(Z))) + (SUN_AREA_SIZE / 2);
      projected_vertex[Y] = ((projected_vertex(Y) * sun_direction(Z) - projected_vertex(Z) * sun_direction(Y)) * 10 / (tile_width * sun_direction(Z))) + (SUN_AREA_SIZE / 2);
      if (!any || projected_vertex(X) > max_x) max_x = projected_vertex(X);
      if (!any || projected_vertex(Y) > max_y) max_y = projected_vertex(Y);
      if (!any || projected_vertex(X) < min_x) min_x = projected_vertex(X);
      if (!any || projected_vertex(Y) < min_y) min_y = projected_vertex(Y);
      any = true;
    }
    assert(any);
    if (min_x < 0) min_x = 0;
    if (min_y < 0) min_y = 0;
    if (max_x >= SUN_AREA_SIZE-1) max_x = SUN_AREA_SIZE-1;
    if (max_y >= SUN_AREA_SIZE-1) max_y = SUN_AREA_SIZE-1;

    for (int x = min_x; x <= max_x; ++x) {
      for (int y = min_y; y <= max_y; ++y) {
        result += !packets.test(x*SUN_AREA_SIZE + y);
        packets.set(x*SUN_AREA_SIZE + y);
      }
    }
    return result;
  }

  int do_bbox(bounding_box bb) {
    int result = 0;

    bb.translate(-world_center_fine_coords);

    fine_scalar max_x = ((bb.max(X) * sun_direction(Z) - (sun_direction(X) > 0 ? bb.max(Z) : bb.min(Z)) * sun_direction(X)) * 10 / (tile_width * sun_direction(Z))) + (SUN_AREA_SIZE / 2);
    fine_scalar min_x = ((bb.min(X) * sun_direction(Z) - (sun_direction(X) > 0 ? bb.min(Z) : bb.max(Z)) * sun_direction(X)) * 10 / (tile_width * sun_direction(Z))) + (SUN_AREA_SIZE / 2);
    fine_scalar max_y = ((bb.max(Y) * sun_direction(Z) - (sun_direction(Y) > 0 ? bb.max(Z) : bb.min(Z)) * sun_direction(Y)) * 10 / (tile_width * sun_direction(Z))) + (SUN_AREA_SIZE / 2);
    fine_scalar min_y = ((bb.min(Y) * sun_direction(Z) - (sun_direction(Y) > 0 ? bb.min(Z) : bb.max(Z)) * sun_direction(Y)) * 10 / (tile_width * sun_direction(Z))) + (SUN_AREA_SIZE / 2);

    if (min_x < 0) min_x = 0;
    if (min_y < 0) min_y = 0;
    if (max_x >= SUN_AREA_SIZE-1) max_x = SUN_AREA_SIZE-1;
    if (max_y >= SUN_AREA_SIZE-1) max_y = SUN_AREA_SIZE-1;
    //std::cerr << max_x - min_x << "\n" << max_y - min_y << "!\n";

    for (int x = min_x; x <= max_x; ++x) {
      for (int y = min_y; y <= max_y; ++y) {
        result += !packets.test(x*SUN_AREA_SIZE + y);
        packets.set(x*SUN_AREA_SIZE + y);
      }
    }
    return result;
  }

  int do_shape(shape const& s) {
    int result = 0;
    for (convex_polyhedron const& p : s.get_polyhedra()) {
      result += do_poly(p);
    }
    for (bounding_box const& b : s.get_boxes()) {
      result += do_bbox(b);
    }
    return result;
  }

  void found(tile_location const& loc) {
    w->litnesses_.insert(std::pair<object_or_tile_identifier, int>(loc, 0)).first->second += do_bbox(fine_bounding_box_of_tile(loc.coords()));
  }
  void found(object_identifier oid) {
    shape const* ods = find_as_pointer(w->get_object_detail_shapes(), oid); assert(ods);
    w->litnesses_.insert(std::pair<object_or_tile_identifier, int>(oid, 0)).first->second += do_shape(*ods);
  }

  world *w;
  vector3<fine_scalar> sun_direction;
};

void world::update_light(vector3<fine_scalar> sun_direction)
{
  litnesses_.clear();
  std::unique_ptr<sunlight_visitor> sv(new sunlight_visitor(this, sun_direction));
  visit_collidable_tiles_and_objects(*sv);
}
<commit_msg>Tweaked the borrowed_bitset optimization<commit_after>/*

    Copyright Eli Dupree and Isaac Dupree, 2011, 2012

    This file is part of Lasercake.

    Lasercake is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Lasercake is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Lasercake.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "world.hpp"
#include "data_structures/borrowed_bitset.hpp"
#include "object_and_tile_iteration.hpp"
#include "data_structures/polygon_collision_detection.hpp"

const int SUN_AREA_SIZE = 5000;

struct sunlight_visitor {
  sunlight_visitor(world *w, vector3<fine_scalar> sun_direction): packets(SUN_AREA_SIZE*SUN_AREA_SIZE),w(w),sun_direction(sun_direction) {}
  borrowed_bitset_that_always_clears_using_memset packets;
  octant_number octant()const { return vector_octant(sun_direction); }
  octant_number octant_; //e.g. from vector_octant()

  int do_poly(convex_polyhedron const& p) {
    int result = 0;
    int max_x, max_y, min_x, min_y;
    bool any = false;
    for (vector3<fine_scalar> const& v : p.vertices()) {
      vector3<fine_scalar> projected_vertex = v;
      projected_vertex -= world_center_fine_coords;
      /*projected_vertex[X] -= projected_vertex(Z) * sun_direction(X) / sun_direction(Z);
      projected_vertex[Y] -= projected_vertex(Z) * sun_direction(Y) / sun_direction(Z);
      projected_vertex[Z] = 0;

      projected_vertex[X] = (projected_vertex(X) * 10 / tile_width) + (SUN_AREA_SIZE / 2);
      projected_vertex[Y] = (projected_vertex(Y) * 10 / tile_width) + (SUN_AREA_SIZE / 2);*/
      projected_vertex[X] = ((projected_vertex(X) * sun_direction(Z) - projected_vertex(Z) * sun_direction(X)) * 10 / (tile_width * sun_direction(Z))) + (SUN_AREA_SIZE / 2);
      projected_vertex[Y] = ((projected_vertex(Y) * sun_direction(Z) - projected_vertex(Z) * sun_direction(Y)) * 10 / (tile_width * sun_direction(Z))) + (SUN_AREA_SIZE / 2);
      if (!any || projected_vertex(X) > max_x) max_x = projected_vertex(X);
      if (!any || projected_vertex(Y) > max_y) max_y = projected_vertex(Y);
      if (!any || projected_vertex(X) < min_x) min_x = projected_vertex(X);
      if (!any || projected_vertex(Y) < min_y) min_y = projected_vertex(Y);
      any = true;
    }
    assert(any);
    if (min_x < 0) min_x = 0;
    if (min_y < 0) min_y = 0;
    if (max_x >= SUN_AREA_SIZE-1) max_x = SUN_AREA_SIZE-1;
    if (max_y >= SUN_AREA_SIZE-1) max_y = SUN_AREA_SIZE-1;

    for (int x = min_x; x <= max_x; ++x) {
      for (int y = min_y; y <= max_y; ++y) {
        result += !packets.test(x*SUN_AREA_SIZE + y);
        packets.set(x*SUN_AREA_SIZE + y);
      }
    }
    return result;
  }

  int do_bbox(bounding_box bb) {
    int result = 0;

    bb.translate(-world_center_fine_coords);

    fine_scalar max_x = ((bb.max(X) * sun_direction(Z) - (sun_direction(X) > 0 ? bb.max(Z) : bb.min(Z)) * sun_direction(X)) * 10 / (tile_width * sun_direction(Z))) + (SUN_AREA_SIZE / 2);
    fine_scalar min_x = ((bb.min(X) * sun_direction(Z) - (sun_direction(X) > 0 ? bb.min(Z) : bb.max(Z)) * sun_direction(X)) * 10 / (tile_width * sun_direction(Z))) + (SUN_AREA_SIZE / 2);
    fine_scalar max_y = ((bb.max(Y) * sun_direction(Z) - (sun_direction(Y) > 0 ? bb.max(Z) : bb.min(Z)) * sun_direction(Y)) * 10 / (tile_width * sun_direction(Z))) + (SUN_AREA_SIZE / 2);
    fine_scalar min_y = ((bb.min(Y) * sun_direction(Z) - (sun_direction(Y) > 0 ? bb.min(Z) : bb.max(Z)) * sun_direction(Y)) * 10 / (tile_width * sun_direction(Z))) + (SUN_AREA_SIZE / 2);

    if (min_x < 0) min_x = 0;
    if (min_y < 0) min_y = 0;
    if (max_x >= SUN_AREA_SIZE-1) max_x = SUN_AREA_SIZE-1;
    if (max_y >= SUN_AREA_SIZE-1) max_y = SUN_AREA_SIZE-1;
    //std::cerr << max_x - min_x << "\n" << max_y - min_y << "!\n";

    for (int x = min_x; x <= max_x; ++x) {
      for (int y = min_y; y <= max_y; ++y) {
        result += !packets.test(x*SUN_AREA_SIZE + y);
        packets.set(x*SUN_AREA_SIZE + y);
      }
    }
    return result;
  }

  int do_shape(shape const& s) {
    int result = 0;
    for (convex_polyhedron const& p : s.get_polyhedra()) {
      result += do_poly(p);
    }
    for (bounding_box const& b : s.get_boxes()) {
      result += do_bbox(b);
    }
    return result;
  }

  void found(tile_location const& loc) {
    w->litnesses_.insert(std::pair<object_or_tile_identifier, int>(loc, 0)).first->second += do_bbox(fine_bounding_box_of_tile(loc.coords()));
  }
  void found(object_identifier oid) {
    shape const* ods = find_as_pointer(w->get_object_detail_shapes(), oid); assert(ods);
    w->litnesses_.insert(std::pair<object_or_tile_identifier, int>(oid, 0)).first->second += do_shape(*ods);
  }

  world *w;
  vector3<fine_scalar> sun_direction;
};

void world::update_light(vector3<fine_scalar> sun_direction)
{
  litnesses_.clear();
  std::unique_ptr<sunlight_visitor> sv(new sunlight_visitor(this, sun_direction));
  visit_collidable_tiles_and_objects(*sv);
}
<|endoftext|>


<commit_before>#define usint unsigned short int
#define uncast reinterpret_cast<unsigned short int>
#define recast reinterpret_cast<char *>
#define rechcast reinterpret_cast<const char *>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sys/time.h>

using namespace std;

struct DirEntry{
    char filename[11];
    char attributes;
    unsigned long created_time;
    usint address;
    unsigned int filesize;
    char reserved[6];
};

usint getFATindex(int);
void setFATindex(int, usint);
char* getDataCluster(int);
void setDataCluster(int,char*);
bool hasNextCluster(int);
DirEntry makeDirEntry(char*,char,usint,unsigned int);
char* getDirRawData(int, char*);
DirEntry* parseDirEntries(char*);
char* packDirEntries(DirEntry*);
vector<string> getTokens(string, char);

const int FAT_OFFSET = 512; // 1 sector
const int DATA_OFFSET = FAT_OFFSET + 256*1024; // 1 sector + 256kB
const int CLUSTER_SIZE = 512*8; // 4kB (8 sectors/cluster at 512B/sector)
const usint FAT_EOF = 0xFFFF;
// DirEntry Attribute Constants
const char ATTR_READONLY = 0x01;
const char ATTR_HIDDEN = 0x02;
const char ATTR_SYSTEMFILE = 0x04;
const char ATTR_VOLUMELABEL = 0x08;
const char ATTR_DIRECTORY = 0x10;
const char ATTR_FILE = 0x20;

fstream FAT;
string CURR_DIR;

int main(int argc, char* argv[]){
    if(argc > 1){
        FAT.open(argv[1], ios::binary | ios::in);
    }else{
        cout << "Please include filename in args" << endl;
        return 0;
    }
    if(!FAT.is_open()){
        cout << "Can't open file!" << endl;
        return 1;
    }
    cout << "File opened succesfully." << endl;
    cout << "READING BOOT SECTOR" << endl;
    char* OS_name = new char[8];
    FAT.seekg(FAT.beg+3);
    FAT.read(OS_name,8);
    cout << "OS NAME: " << OS_name << endl;
    /* Check FS Initalized status */
    cout << "Checking FS status..." << endl;
    cout << "FAT index 0: " << getFATindex(0) << endl;
    cout << "FAT index 1: " << getFATindex(1) << endl;
    cout << "FAT index 2 (ROOT): " << getFATindex(2) << endl;
    if (getFATindex(2)==0){
        cout << "FAT still uninitalized. Writing root..." << endl;
        DirEntry* root = parseDirEntries(getDataCluster(2));
        root[0]=makeDirEntry(".",ATTR_DIRECTORY | ATTR_SYSTEMFILE,2,0);
        root[1]=makeDirEntry("..",ATTR_DIRECTORY | ATTR_SYSTEMFILE,2,0);
        setDataCluster(2,packDirEntries(root));
        setFATindex(2,FAT_EOF);
        cout << "Root written." << endl;
    }
    //Welcome to the shell
    int status = 0;
	while(!status) {
		cout << OS_name << "> ";
		string line;
		getline(cin,line);
		vector<string> tokens = getTokens(line, ' ');
        if(tokens.size() > 0)
            cout << "cmd to execute: " << tokens[0] << endl;
        if(tokens.size() == 0 || tokens[0] == "exit")
            status = 1;
		//status = executeCommand(tokens);
	};
    if(status != 1){
		cerr << "ERROR " << status << ": al ejecutar el comando" << endl;
	}
    delete[] OS_name;
    FAT.close();
    return 0;
}

usint getFATindex(int index){
    FAT.seekg(FAT.beg+FAT_OFFSET+(index*2));
    usint value;
    FAT.read(recast(&value),2);
    return value;
}

void setFATindex(int index, usint value){
    FAT.seekg(FAT.beg+FAT_OFFSET+(index*2));
    FAT.write(rechcast(&value),2);
}

char* getDataCluster(int index){
    FAT.seekg(FAT.beg+DATA_OFFSET+(index*CLUSTER_SIZE));
    char* data = new char[CLUSTER_SIZE];
    FAT.read(data,CLUSTER_SIZE);
    return data;
}

void setDataCluster(int index, char* data){
    FAT.seekg(FAT.beg+DATA_OFFSET+(index*CLUSTER_SIZE));
    FAT.write(data,CLUSTER_SIZE);
}

bool hasNextCluster(int index){
    return getFATindex(index)!=FAT_EOF;
}

DirEntry makeDirEntry(char* fn, char attr, usint addr, unsigned int size){
    DirEntry entry;
    //entry.filename=fn;
    for(int i=0; i<11; i++){
        entry.filename[i]=fn[i];
        if(fn[i]=='\0'){
            break;
        }
    }
    entry.attributes=attr;
    struct timeval tp;
    gettimeofday(&tp, NULL);
    entry.created_time = tp.tv_sec * 1000 + tp.tv_usec / 1000;
    //entry.created_time=std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);
    entry.address=addr;
    entry.filesize=size;
    return entry;
}

char* getDirRawData(int index, char* data){
    char* entry = new char[32];
    for(int i=0; i<32; i++){
        entry[i]=data[index*32+i];
    }
    return entry;
}

/**
    Transforms a 4kB cluster of data into 512 DirEntries.

    @param data The 4kB cluster as a char array.
    @return The array of 512 DirEntries.
*/
DirEntry* parseDirEntries(char* data){
    DirEntry* entries = new DirEntry[512];
    for(int i=0; i<512; i++){
        entries[i] = *(reinterpret_cast<DirEntry*>(getDirRawData(i,data)));
    }
    return entries;
}

/**
    The reverse of parseDirEntries. It packs 512 DirEntries into a 4kB cluster.

    @param entries Array of 512 DirEntries to pack.
    @return The 4kB cluster as a char array.
*/
char* packDirEntries(DirEntry* entries){
    char* data = new char[CLUSTER_SIZE];
    char* entry;
    for(int i=0; i<512; i++){
        entry=recast(&(entries[i]));
        for(int j=0; j<32; j++){
            data[i*32+j]=entry[j];
        }
    }
    return data;
}

/**
    Only works with one char delimiter but it works!!

    @param entries Array of 512 DirEntries to pack.
    @return The 4kB cluster as a char array.
*/
vector<string> getTokens(string toTokenize, char delimiter){
	vector<string> v;
	string::iterator stringIT = toTokenize.begin();
	for(string::iterator i = toTokenize.begin(); i != toTokenize.end(); i++){
		if(*i == delimiter){
			v.push_back(string(stringIT,i));
			stringIT=i+1;
		}
	}
	v.push_back(string(stringIT,toTokenize.end()));
	return v;
}<commit_msg>Implemented(?) ls. What's going on?<commit_after>#define usint unsigned short int
#define uncast reinterpret_cast<unsigned short int>
#define recast reinterpret_cast<char *>
#define rechcast reinterpret_cast<const char *>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sys/time.h>

using namespace std;

struct DirEntry{
    char filename[11];
    char attributes;
    unsigned long created_time;
    usint address;
    unsigned int filesize;
    char reserved[6];
};

usint getFATindex(int);
void setFATindex(int, usint);
char* getDataCluster(int);
void setDataCluster(int,char*);
bool hasNextCluster(int);
DirEntry makeDirEntry(char*,char,usint,unsigned int);
char* getDirRawData(int, char*);
DirEntry* parseDirEntries(char*);
char* packDirEntries(DirEntry*);
vector<string> getTokens(string, char);

const int FAT_OFFSET = 512; // 1 sector
const int DATA_OFFSET = FAT_OFFSET + 256*1024; // 1 sector + 256kB
const int CLUSTER_SIZE = 512*8; // 4kB (8 sectors/cluster at 512B/sector)
const usint FAT_EOF = 0xFFFF;
// DirEntry Attribute Constants
const char ATTR_READONLY = 0x01;
const char ATTR_HIDDEN = 0x02;
const char ATTR_SYSTEMFILE = 0x04;
const char ATTR_VOLUMELABEL = 0x08;
const char ATTR_DIRECTORY = 0x10;
const char ATTR_FILE = 0x20;

fstream FAT;
string currentDir="/";
int currentIndex=2;

int main(int argc, char* argv[]){
    if(argc > 1){
        FAT.open(argv[1], ios::binary | ios::in);
    }else{
        cout << "Please include filename in args" << endl;
        return 0;
    }
    if(!FAT.is_open()){
        cout << "Can't open file!" << endl;
        return 1;
    }
    cout << "File opened succesfully." << endl;
    cout << "READING BOOT SECTOR" << endl;
    char* OS_name = new char[8];
    FAT.seekg(FAT.beg+3);
    FAT.read(OS_name,8);
    cout << "OS NAME: " << OS_name << endl;
    /* Check FS Initalized status */
    cout << "Checking FS status..." << endl;
    cout << "FAT index 0: " << getFATindex(0) << endl;
    cout << "FAT index 1: " << getFATindex(1) << endl;
    cout << "FAT index 2 (ROOT): " << getFATindex(2) << endl;
    if (getFATindex(2)==0){
        cout << "FAT still uninitalized. Writing root..." << endl;
        DirEntry* root = parseDirEntries(getDataCluster(2));
        root[0]=makeDirEntry(".",ATTR_DIRECTORY | ATTR_SYSTEMFILE,2,0);
        root[1]=makeDirEntry("..",ATTR_DIRECTORY | ATTR_SYSTEMFILE,2,0);
        setDataCluster(2,packDirEntries(root));
        setFATindex(2,FAT_EOF);
        cout << "Root written." << endl;
    }
    //Welcome to the shell
    int status = 0;
	while(!status) {
		cout << OS_name << "> ";
		string line;
		getline(cin,line);
		vector<string> tokens = getTokens(line, ' ');
        if(tokens.size() > 0)
            cout << "cmd to execute: " << tokens[0] << endl;
        if(tokens.size() == 0 || tokens[0] == "exit"){
            status = 1;
        }else if(tokens[0]=="ls"){
            DirEntry* myDir = parseDirEntries(getDataCluster(currentIndex));
            cout << "Filename   |Type |Date      |Size" << endl;
            cout << "=======================================" << endl;
            for(int i=0; i<512; i++){
                if(myDir[i].filename[0]!='\0'){//Check if valid DirEntry
                    cout << myDir[i].filename << " ";
                    if(myDir[i].attributes & ATTR_DIRECTORY){
                        cout << "DIR  ";
                    }else{
                        cout << "FILE ";
                    }
                    cout << myDir[i].created_time; //UNFORMATTED!!!
                    cout << myDir[i].filesize << "B" << endl;
                }
            }
        }
        //status = executeCommand(tokens);
	};
    if(status != 1){
		cerr << "ERROR " << status << ": al ejecutar el comando" << endl;
	}
    delete[] OS_name;
    FAT.close();
    return 0;
}

usint getFATindex(int index){
    FAT.seekg(FAT.beg+FAT_OFFSET+(index*2));
    usint value;
    FAT.read(recast(&value),2);
    return value;
}

void setFATindex(int index, usint value){
    FAT.seekg(FAT.beg+FAT_OFFSET+(index*2));
    FAT.write(rechcast(&value),2);
}

char* getDataCluster(int index){
    FAT.seekg(FAT.beg+DATA_OFFSET+(index*CLUSTER_SIZE));
    char* data = new char[CLUSTER_SIZE];
    FAT.read(data,CLUSTER_SIZE);
    return data;
}

void setDataCluster(int index, char* data){
    FAT.seekg(FAT.beg+DATA_OFFSET+(index*CLUSTER_SIZE));
    FAT.write(data,CLUSTER_SIZE);
}

bool hasNextCluster(int index){
    return getFATindex(index)!=FAT_EOF;
}

DirEntry makeDirEntry(char* fn, char attr, usint addr, unsigned int size){
    DirEntry entry;
    //entry.filename=fn;
    for(int i=0; i<11; i++){
        entry.filename[i]=fn[i];
        if(fn[i]=='\0'){
            break;
        }
    }
    entry.attributes=attr;
    struct timeval tp;
    gettimeofday(&tp, NULL);
    entry.created_time = tp.tv_sec * 1000 + tp.tv_usec / 1000;
    //entry.created_time=std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);
    entry.address=addr;
    entry.filesize=size;
    return entry;
}

char* getDirRawData(int index, char* data){
    char* entry = new char[32];
    for(int i=0; i<32; i++){
        entry[i]=data[index*32+i];
    }
    return entry;
}

/**
    Transforms a 4kB cluster of data into 512 DirEntries.

    @param data The 4kB cluster as a char array.
    @return The array of 512 DirEntries.
*/
DirEntry* parseDirEntries(char* data){
    DirEntry* entries = new DirEntry[512];
    for(int i=0; i<512; i++){
        entries[i] = *(reinterpret_cast<DirEntry*>(getDirRawData(i,data)));
    }
    return entries;
}

/**
    The reverse of parseDirEntries. It packs 512 DirEntries into a 4kB cluster.

    @param entries Array of 512 DirEntries to pack.
    @return The 4kB cluster as a char array.
*/
char* packDirEntries(DirEntry* entries){
    char* data = new char[CLUSTER_SIZE];
    char* entry;
    for(int i=0; i<512; i++){
        entry=recast(&(entries[i]));
        for(int j=0; j<32; j++){
            data[i*32+j]=entry[j];
        }
    }
    return data;
}

/**
    Only works with one char delimiter but it works!!
*/
vector<string> getTokens(string toTokenize, char delimiter){
	vector<string> v;
	string::iterator stringIT = toTokenize.begin();
	for(string::iterator i = toTokenize.begin(); i != toTokenize.end(); i++){
		if(*i == delimiter){
			v.push_back(string(stringIT,i));
			stringIT=i+1;
		}
	}
	v.push_back(string(stringIT,toTokenize.end()));
	return v;
}<|endoftext|>


<commit_before>// Copyright Daniel Wallin & Arvid Norberg 2009. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <libtorrent/create_torrent.hpp>
#include <libtorrent/file_storage.hpp>
#include "libtorrent/intrusive_ptr_base.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{
    void set_hash(create_torrent& c, int p, char const* hash)
    {
        c.set_hash(p, sha1_hash(hash));
    }

    void call_python_object(boost::python::object const& obj, int i)
    {
       obj(i);
    }

#ifndef BOOST_NO_EXCEPTIONS
    void set_piece_hashes_callback(create_torrent& c, std::string const& p
        , boost::python::object cb)
    {
        set_piece_hashes(c, p, boost::bind(call_python_object, cb, _1));
    }
#else
    void set_piece_hashes_callback(create_torrent& c, std::string const& p
        , boost::python::object cb)
    {
        error_code ec;
        set_piece_hashes(c, p, boost::bind(call_python_object, cb, _1), ec);
    }

    void set_piece_hashes0(create_torrent& c, std::string const & s)
    {
        error_code ec;
        set_piece_hashes(c, s, ec);
    }
#endif

    void add_node(create_torrent& ct, std::string const& addr, int port)
    {
        ct.add_node(std::make_pair(addr, port));
    }

    void add_file(file_storage& ct, file_entry const& fe)
    {
       ct.add_file(fe);
    }
}

void bind_create_torrent()
{
    void (file_storage::*add_file0)(std::string const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
#if TORRENT_USE_WSTRING
    void (file_storage::*add_file1)(std::wstring const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
#endif

    void (file_storage::*set_name0)(std::string const&) = &file_storage::set_name;
#if TORRENT_USE_WSTRING
    void (file_storage::*set_name1)(std::wstring const&) = &file_storage::set_name;
#endif

#ifndef BOOST_NO_EXCEPTIONS
    void (*set_piece_hashes0)(create_torrent&, std::string const&) = &set_piece_hashes;
#endif
    void (*add_files0)(file_storage&, std::string const&, boost::uint32_t) = add_files;

    file_entry (file_storage::*at)(int) const = &file_storage::at;

    class_<file_storage>("file_storage")
        .def("is_valid", &file_storage::is_valid)
        .def("add_file", add_file, arg("entry"))
        .def("add_file", add_file0, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
#if TORRENT_USE_WSTRING
        .def("add_file", add_file1, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
#endif
        .def("num_files", &file_storage::num_files)
        .def("at", at)
//        .def("hash", &file_storage::hash)
//        .def("symlink", &file_storage::symlink, return_internal_reference<>())
//        .def("file_index", &file_storage::file_index)
//        .def("file_base", &file_storage::file_base)
//        .def("set_file_base", &file_storage::set_file_base)
//        .def("file_path", &file_storage::file_path)
        .def("total_size", &file_storage::total_size)
        .def("set_num_pieces", &file_storage::set_num_pieces)
        .def("num_pieces", &file_storage::num_pieces)
        .def("set_piece_length", &file_storage::set_piece_length)
        .def("piece_length", &file_storage::piece_length)
        .def("piece_size", &file_storage::piece_size)
        .def("set_name", set_name0)
#if TORRENT_USE_WSTRING
        .def("set_name", set_name1)
#endif
        .def("name", &file_storage::name, return_internal_reference<>())
        ;

    class_<create_torrent>("create_torrent", no_init)
        .def(init<file_storage&>())
        .def(init<file_storage&, torrent_info const&>(arg("ti")))
        .def(init<file_storage&, int, int, int>((arg("storage"), arg("piece_size") = 0
            , arg("pad_file_limit") = -1, arg("flags") = int(libtorrent::create_torrent::optimize))))

        .def("generate", &create_torrent::generate)

        .def("files", &create_torrent::files, return_internal_reference<>())
        .def("set_comment", &create_torrent::set_comment)
        .def("set_creator", &create_torrent::set_creator)
        .def("set_hash", &set_hash)
        .def("add_url_seed", &create_torrent::add_url_seed)
        .def("add_node", &add_node)
        .def("add_tracker", &create_torrent::add_tracker, (arg("announce_url"), arg("tier") = 0))
        .def("set_priv", &create_torrent::set_priv)
        .def("num_pieces", &create_torrent::num_pieces)
        .def("piece_length", &create_torrent::piece_length)
        .def("piece_size", &create_torrent::piece_size)
        .def("priv", &create_torrent::priv)
        ;

    enum_<create_torrent::flags_t>("create_torrent_flags_t")
        .value("optimize", create_torrent::optimize)
        .value("merkle", create_torrent::merkle)
        .value("modification_time", create_torrent::modification_time)
        .value("symlinks", create_torrent::symlinks)
    ;

    def("add_files", add_files0, (arg("fs"), arg("path"), arg("flags") = 0));
    def("set_piece_hashes", set_piece_hashes0);
    def("set_piece_hashes", set_piece_hashes_callback);

}
<commit_msg>fixed typo in python binding<commit_after>// Copyright Daniel Wallin & Arvid Norberg 2009. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <libtorrent/create_torrent.hpp>
#include <libtorrent/file_storage.hpp>
#include "libtorrent/intrusive_ptr_base.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{
    void set_hash(create_torrent& c, int p, char const* hash)
    {
        c.set_hash(p, sha1_hash(hash));
    }

    void call_python_object(boost::python::object const& obj, int i)
    {
       obj(i);
    }

#ifndef BOOST_NO_EXCEPTIONS
    void set_piece_hashes_callback(create_torrent& c, std::string const& p
        , boost::python::object cb)
    {
        set_piece_hashes(c, p, boost::bind(call_python_object, cb, _1));
    }
#else
    void set_piece_hashes_callback(create_torrent& c, std::string const& p
        , boost::python::object cb)
    {
        error_code ec;
        set_piece_hashes(c, p, boost::bind(call_python_object, cb, _1), ec);
    }

    void set_piece_hashes0(create_torrent& c, std::string const & s)
    {
        error_code ec;
        set_piece_hashes(c, s, ec);
    }
#endif

    void add_node(create_torrent& ct, std::string const& addr, int port)
    {
        ct.add_node(std::make_pair(addr, port));
    }

    void add_file(file_storage& ct, file_entry const& fe)
    {
       ct.add_file(fe);
    }
}

void bind_create_torrent()
{
    void (file_storage::*add_file0)(std::string const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
#if TORRENT_USE_WSTRING
    void (file_storage::*add_file1)(std::wstring const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
#endif

    void (file_storage::*set_name0)(std::string const&) = &file_storage::set_name;
#if TORRENT_USE_WSTRING
    void (file_storage::*set_name1)(std::wstring const&) = &file_storage::set_name;
#endif

#ifndef BOOST_NO_EXCEPTIONS
    void (*set_piece_hashes0)(create_torrent&, std::string const&) = &set_piece_hashes;
#endif
    void (*add_files0)(file_storage&, std::string const&, boost::uint32_t) = add_files;

    file_entry (file_storage::*at)(int) const = &file_storage::at;

    class_<file_storage>("file_storage")
        .def("is_valid", &file_storage::is_valid)
        .def("add_file", add_file, arg("entry"))
        .def("add_file", add_file0, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
#if TORRENT_USE_WSTRING
        .def("add_file", add_file1, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
#endif
        .def("num_files", &file_storage::num_files)
        .def("at", at)
//        .def("hash", &file_storage::hash)
//        .def("symlink", &file_storage::symlink, return_internal_reference<>())
//        .def("file_index", &file_storage::file_index)
//        .def("file_base", &file_storage::file_base)
//        .def("set_file_base", &file_storage::set_file_base)
//        .def("file_path", &file_storage::file_path)
        .def("total_size", &file_storage::total_size)
        .def("set_num_pieces", &file_storage::set_num_pieces)
        .def("num_pieces", &file_storage::num_pieces)
        .def("set_piece_length", &file_storage::set_piece_length)
        .def("piece_length", &file_storage::piece_length)
        .def("piece_size", &file_storage::piece_size)
        .def("set_name", set_name0)
#if TORRENT_USE_WSTRING
        .def("set_name", set_name1)
#endif
        .def("name", &file_storage::name, return_internal_reference<>())
        ;

    class_<create_torrent>("create_torrent", no_init)
        .def(init<file_storage&>())
        .def(init<torrent_info const&>(arg("ti")))
        .def(init<file_storage&, int, int, int>((arg("storage"), arg("piece_size") = 0
            , arg("pad_file_limit") = -1, arg("flags") = int(libtorrent::create_torrent::optimize))))

        .def("generate", &create_torrent::generate)

        .def("files", &create_torrent::files, return_internal_reference<>())
        .def("set_comment", &create_torrent::set_comment)
        .def("set_creator", &create_torrent::set_creator)
        .def("set_hash", &set_hash)
        .def("add_url_seed", &create_torrent::add_url_seed)
        .def("add_node", &add_node)
        .def("add_tracker", &create_torrent::add_tracker, (arg("announce_url"), arg("tier") = 0))
        .def("set_priv", &create_torrent::set_priv)
        .def("num_pieces", &create_torrent::num_pieces)
        .def("piece_length", &create_torrent::piece_length)
        .def("piece_size", &create_torrent::piece_size)
        .def("priv", &create_torrent::priv)
        ;

    enum_<create_torrent::flags_t>("create_torrent_flags_t")
        .value("optimize", create_torrent::optimize)
        .value("merkle", create_torrent::merkle)
        .value("modification_time", create_torrent::modification_time)
        .value("symlinks", create_torrent::symlinks)
    ;

    def("add_files", add_files0, (arg("fs"), arg("path"), arg("flags") = 0));
    def("set_piece_hashes", set_piece_hashes0);
    def("set_piece_hashes", set_piece_hashes_callback);

}
<|endoftext|>


<commit_before>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <boost/python/tuple.hpp>
#include <libtorrent/torrent_handle.hpp>
#include <boost/lexical_cast.hpp>
#include "gil.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{

  list url_seeds(torrent_handle& handle)
  {
      list ret;
      std::set<std::string> urls;
      {
          allow_threading_guard guard;
          urls = handle.url_seeds();
      }

      for (std::set<std::string>::iterator i(urls.begin())
          , end(urls.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_availability(torrent_handle& handle)
  {
      list ret;
      std::vector<int> avail;
      {
          allow_threading_guard guard;
          handle.piece_availability(avail);
      }

      for (std::vector<int>::iterator i(avail.begin())
          , end(avail.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_priorities(torrent_handle& handle)
  {
      list ret;
      std::vector<int> prio;
      {
          allow_threading_guard guard;
          prio = handle.piece_priorities();
      }

      for (std::vector<int>::iterator i(prio.begin())
          , end(prio.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  std::vector<announce_entry>::const_iterator begin_trackers(torrent_handle& i)
  {
      allow_threading_guard guard;
      return i.trackers().begin();
  }

  std::vector<announce_entry>::const_iterator end_trackers(torrent_handle& i)
  {
      allow_threading_guard guard;
      return i.trackers().end();
  }

} // namespace unnamed

list file_progress(torrent_handle& handle)
{
    std::vector<size_type> p;

    {
        allow_threading_guard guard;
        p.reserve(handle.get_torrent_info().num_files());
        handle.file_progress(p);
    }

    list result;

    for (std::vector<size_type>::iterator i(p.begin()), e(p.end()); i != e; ++i)
        result.append(*i);

    return result;
}

list get_peer_info(torrent_handle const& handle)
{
    std::vector<peer_info> pi;

    {
        allow_threading_guard guard;
        handle.get_peer_info(pi);
    }

    list result;

    for (std::vector<peer_info>::iterator i = pi.begin(); i != pi.end(); ++i)
        result.append(*i);

    return result;
}

void prioritize_pieces(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_pieces(result);
      return;
   }
}

void prioritize_files(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_files(result);
      return;
   }
}

list file_priorities(torrent_handle& handle)
{
    list ret;
    std::vector<int> priorities = handle.file_priorities();

    for (std::vector<int>::iterator i = priorities.begin(); i != priorities.end(); ++i)
        ret.append(*i);

    return ret;
}

void replace_trackers(torrent_handle& info, object trackers)
{
    object iter(trackers.attr("__iter__")());

    std::vector<announce_entry> result;

    for (;;)
    {
        handle<> entry(allow_null(PyIter_Next(iter.ptr())));

        if (entry == handle<>())
            break;

        result.push_back(extract<announce_entry const&>(object(entry)));
    }

    allow_threading_guard guard;
    info.replace_trackers(result);
}

list get_download_queue(torrent_handle& handle)
{
    using boost::python::make_tuple;

    list ret;

    std::vector<partial_piece_info> downloading;

    {
        allow_threading_guard guard;
        handle.get_download_queue(downloading);
    }

    for (std::vector<partial_piece_info>::iterator i = downloading.begin()
        , end(downloading.end()); i != end; ++i)
    {
        dict partial_piece;
        partial_piece["piece_index"] = i->piece_index;
        partial_piece["blocks_in_piece"] = i->blocks_in_piece;
        list block_list;
        for (int k = 0; k < i->blocks_in_piece; ++k)
        {
            dict block_info;
            block_info["state"] = i->blocks[k].state;
            block_info["num_peers"] = i->blocks[k].num_peers;
            block_info["bytes_progress"] = i->blocks[k].bytes_progress;
            block_info["block_size"] = i->blocks[k].block_size;
            block_info["peer"] = make_tuple(
                boost::lexical_cast<std::string>(i->blocks[k].peer.address()), i->blocks[k].peer.port());
            block_list.append(block_info);
        }
        partial_piece["blocks"] = block_list;

        ret.append(partial_piece);
    }

    return ret;
}

namespace
{
    tcp::endpoint tuple_to_endpoint(tuple const& t)
    {
        return tcp::endpoint(address::from_string(extract<std::string>(t[0])), extract<int>(t[1]));
    }
}

void force_reannounce(torrent_handle& th, int s)
{
    th.force_reannounce(boost::posix_time::seconds(s));
}

void connect_peer(torrent_handle& th, tuple ip, int source)
{
    th.connect_peer(tuple_to_endpoint(ip), source);
}

void set_peer_upload_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_upload_limit(tuple_to_endpoint(ip), limit);
}

void set_peer_download_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_download_limit(tuple_to_endpoint(ip), limit);
}

void add_piece(torrent_handle& th, int piece, char const *data, int flags)
{
   th.add_piece(piece, data, flags);
}

void bind_torrent_handle()
{
    void (torrent_handle::*force_reannounce0)() const = &torrent_handle::force_reannounce;

    int (torrent_handle::*piece_priority0)(int) const = &torrent_handle::piece_priority;
    void (torrent_handle::*piece_priority1)(int, int) const = &torrent_handle::piece_priority;

    void (torrent_handle::*move_storage0)(fs::path const&) const = &torrent_handle::move_storage;
    void (torrent_handle::*move_storage1)(fs::wpath const&) const = &torrent_handle::move_storage;

    void (torrent_handle::*rename_file0)(int, fs::path const&) const = &torrent_handle::rename_file;
    void (torrent_handle::*rename_file1)(int, fs::wpath const&) const = &torrent_handle::rename_file;

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
    bool (torrent_handle::*resolve_countries0)() const = &torrent_handle::resolve_countries;
    void (torrent_handle::*resolve_countries1)(bool) = &torrent_handle::resolve_countries;
#endif

#define _ allow_threads

    class_<torrent_handle>("torrent_handle")
        .def("get_peer_info", get_peer_info)
        .def("status", _(&torrent_handle::status))
        .def("get_download_queue", get_download_queue)
        .def("file_progress", file_progress)
        .def("trackers", range(begin_trackers, end_trackers))
        .def("replace_trackers", replace_trackers)
        .def("add_url_seed", _(&torrent_handle::add_url_seed))
        .def("remove_url_seed", _(&torrent_handle::remove_url_seed))
        .def("url_seeds", url_seeds)
        .def("has_metadata", _(&torrent_handle::has_metadata))
        .def("get_torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>())
        .def("is_valid", _(&torrent_handle::is_valid))
        .def("is_seed", _(&torrent_handle::is_seed))
        .def("is_finished", _(&torrent_handle::is_finished))
        .def("is_paused", _(&torrent_handle::is_paused))
        .def("pause", _(&torrent_handle::pause))
        .def("resume", _(&torrent_handle::resume))
        .def("clear_error", _(&torrent_handle::clear_error))

        .def("is_auto_managed", _(&torrent_handle::is_auto_managed))
        .def("auto_managed", _(&torrent_handle::auto_managed))
        .def("queue_position", _(&torrent_handle::queue_position))
        .def("queue_position_up", _(&torrent_handle::queue_position_up))
        .def("queue_position_down", _(&torrent_handle::queue_position_down))
        .def("queue_position_top", _(&torrent_handle::queue_position_top))
        .def("queue_position_bottom", _(&torrent_handle::queue_position_bottom))

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
        .def("resolve_countries", _(resolve_countries0))
        .def("resolve_countries", _(resolve_countries1))
#endif
        // deprecated
#ifndef TORRENT_NO_DEPRECATE
        .def("filter_piece", _(&torrent_handle::filter_piece))
        .def("is_piece_filtered", _(&torrent_handle::is_piece_filtered))
        .def("write_resume_data", _(&torrent_handle::write_resume_data))
#endif
        .def("add_piece", add_piece)
        .def("read_piece", _(&torrent_handle::read_piece))
        .def("piece_availability", piece_availability)
        .def("piece_priority", _(piece_priority0))
        .def("piece_priority", _(piece_priority1))
        .def("prioritize_pieces", prioritize_pieces)
        .def("piece_priorities", piece_priorities)
        .def("prioritize_files", prioritize_files)
        .def("file_priorities", file_priorities)
        .def("use_interface", &torrent_handle::use_interface)
        .def("save_resume_data", _(&torrent_handle::save_resume_data))
        .def("force_reannounce", _(force_reannounce0))
        .def("force_reannounce", force_reannounce)
        .def("scrape_tracker", _(&torrent_handle::scrape_tracker))
        .def("name", _(&torrent_handle::name))
        .def("set_upload_limit", _(&torrent_handle::set_upload_limit))
        .def("upload_limit", _(&torrent_handle::upload_limit))
        .def("set_download_limit", _(&torrent_handle::set_download_limit))
        .def("download_limit", _(&torrent_handle::download_limit))
        .def("set_sequential_download", _(&torrent_handle::set_sequential_download))
        .def("set_peer_upload_limit", set_peer_upload_limit)
        .def("set_peer_download_limit", set_peer_download_limit)
        .def("connect_peer", connect_peer)
        .def("set_ratio", _(&torrent_handle::set_ratio))
        .def("save_path", _(&torrent_handle::save_path))
        .def("set_max_uploads", _(&torrent_handle::set_max_uploads))
        .def("set_max_connections", _(&torrent_handle::set_max_connections))
        .def("set_tracker_login", _(&torrent_handle::set_tracker_login))
        .def("move_storage", _(move_storage0))
        .def("move_storage", _(move_storage1))
        .def("info_hash", _(&torrent_handle::info_hash))
        .def("force_recheck", _(&torrent_handle::force_recheck))
        .def("rename_file", _(rename_file0))
        .def("rename_file", _(rename_file1))
        ;
}
<commit_msg>updated python bindings with the recent API change<commit_after>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <boost/python/tuple.hpp>
#include <libtorrent/torrent_handle.hpp>
#include <boost/lexical_cast.hpp>
#include "gil.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{

  list url_seeds(torrent_handle& handle)
  {
      list ret;
      std::set<std::string> urls;
      {
          allow_threading_guard guard;
          urls = handle.url_seeds();
      }

      for (std::set<std::string>::iterator i(urls.begin())
          , end(urls.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_availability(torrent_handle& handle)
  {
      list ret;
      std::vector<int> avail;
      {
          allow_threading_guard guard;
          handle.piece_availability(avail);
      }

      for (std::vector<int>::iterator i(avail.begin())
          , end(avail.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_priorities(torrent_handle& handle)
  {
      list ret;
      std::vector<int> prio;
      {
          allow_threading_guard guard;
          prio = handle.piece_priorities();
      }

      for (std::vector<int>::iterator i(prio.begin())
          , end(prio.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  std::vector<announce_entry>::const_iterator begin_trackers(torrent_handle& i)
  {
      allow_threading_guard guard;
      return i.trackers().begin();
  }

  std::vector<announce_entry>::const_iterator end_trackers(torrent_handle& i)
  {
      allow_threading_guard guard;
      return i.trackers().end();
  }

} // namespace unnamed

list file_progress(torrent_handle& handle)
{
    std::vector<size_type> p;

    {
        allow_threading_guard guard;
        p.reserve(handle.get_torrent_info().num_files());
        handle.file_progress(p);
    }

    list result;

    for (std::vector<size_type>::iterator i(p.begin()), e(p.end()); i != e; ++i)
        result.append(*i);

    return result;
}

list get_peer_info(torrent_handle const& handle)
{
    std::vector<peer_info> pi;

    {
        allow_threading_guard guard;
        handle.get_peer_info(pi);
    }

    list result;

    for (std::vector<peer_info>::iterator i = pi.begin(); i != pi.end(); ++i)
        result.append(*i);

    return result;
}

void prioritize_pieces(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_pieces(result);
      return;
   }
}

void prioritize_files(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_files(result);
      return;
   }
}

list file_priorities(torrent_handle& handle)
{
    list ret;
    std::vector<int> priorities = handle.file_priorities();

    for (std::vector<int>::iterator i = priorities.begin(); i != priorities.end(); ++i)
        ret.append(*i);

    return ret;
}

void replace_trackers(torrent_handle& info, object trackers)
{
    object iter(trackers.attr("__iter__")());

    std::vector<announce_entry> result;

    for (;;)
    {
        handle<> entry(allow_null(PyIter_Next(iter.ptr())));

        if (entry == handle<>())
            break;

        result.push_back(extract<announce_entry const&>(object(entry)));
    }

    allow_threading_guard guard;
    info.replace_trackers(result);
}

list get_download_queue(torrent_handle& handle)
{
    using boost::python::make_tuple;

    list ret;

    std::vector<partial_piece_info> downloading;

    {
        allow_threading_guard guard;
        handle.get_download_queue(downloading);
    }

    for (std::vector<partial_piece_info>::iterator i = downloading.begin()
        , end(downloading.end()); i != end; ++i)
    {
        dict partial_piece;
        partial_piece["piece_index"] = i->piece_index;
        partial_piece["blocks_in_piece"] = i->blocks_in_piece;
        list block_list;
        for (int k = 0; k < i->blocks_in_piece; ++k)
        {
            dict block_info;
            block_info["state"] = i->blocks[k].state;
            block_info["num_peers"] = i->blocks[k].num_peers;
            block_info["bytes_progress"] = i->blocks[k].bytes_progress;
            block_info["block_size"] = i->blocks[k].block_size;
            block_info["peer"] = make_tuple(
                boost::lexical_cast<std::string>(i->blocks[k].peer().address()), i->blocks[k].peer().port());
            block_list.append(block_info);
        }
        partial_piece["blocks"] = block_list;

        ret.append(partial_piece);
    }

    return ret;
}

namespace
{
    tcp::endpoint tuple_to_endpoint(tuple const& t)
    {
        return tcp::endpoint(address::from_string(extract<std::string>(t[0])), extract<int>(t[1]));
    }
}

void force_reannounce(torrent_handle& th, int s)
{
    th.force_reannounce(boost::posix_time::seconds(s));
}

void connect_peer(torrent_handle& th, tuple ip, int source)
{
    th.connect_peer(tuple_to_endpoint(ip), source);
}

void set_peer_upload_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_upload_limit(tuple_to_endpoint(ip), limit);
}

void set_peer_download_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_download_limit(tuple_to_endpoint(ip), limit);
}

void add_piece(torrent_handle& th, int piece, char const *data, int flags)
{
   th.add_piece(piece, data, flags);
}

void bind_torrent_handle()
{
    void (torrent_handle::*force_reannounce0)() const = &torrent_handle::force_reannounce;

    int (torrent_handle::*piece_priority0)(int) const = &torrent_handle::piece_priority;
    void (torrent_handle::*piece_priority1)(int, int) const = &torrent_handle::piece_priority;

    void (torrent_handle::*move_storage0)(fs::path const&) const = &torrent_handle::move_storage;
    void (torrent_handle::*move_storage1)(fs::wpath const&) const = &torrent_handle::move_storage;

    void (torrent_handle::*rename_file0)(int, fs::path const&) const = &torrent_handle::rename_file;
    void (torrent_handle::*rename_file1)(int, fs::wpath const&) const = &torrent_handle::rename_file;

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
    bool (torrent_handle::*resolve_countries0)() const = &torrent_handle::resolve_countries;
    void (torrent_handle::*resolve_countries1)(bool) = &torrent_handle::resolve_countries;
#endif

#define _ allow_threads

    class_<torrent_handle>("torrent_handle")
        .def("get_peer_info", get_peer_info)
        .def("status", _(&torrent_handle::status))
        .def("get_download_queue", get_download_queue)
        .def("file_progress", file_progress)
        .def("trackers", range(begin_trackers, end_trackers))
        .def("replace_trackers", replace_trackers)
        .def("add_url_seed", _(&torrent_handle::add_url_seed))
        .def("remove_url_seed", _(&torrent_handle::remove_url_seed))
        .def("url_seeds", url_seeds)
        .def("has_metadata", _(&torrent_handle::has_metadata))
        .def("get_torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>())
        .def("is_valid", _(&torrent_handle::is_valid))
        .def("is_seed", _(&torrent_handle::is_seed))
        .def("is_finished", _(&torrent_handle::is_finished))
        .def("is_paused", _(&torrent_handle::is_paused))
        .def("pause", _(&torrent_handle::pause))
        .def("resume", _(&torrent_handle::resume))
        .def("clear_error", _(&torrent_handle::clear_error))

        .def("is_auto_managed", _(&torrent_handle::is_auto_managed))
        .def("auto_managed", _(&torrent_handle::auto_managed))
        .def("queue_position", _(&torrent_handle::queue_position))
        .def("queue_position_up", _(&torrent_handle::queue_position_up))
        .def("queue_position_down", _(&torrent_handle::queue_position_down))
        .def("queue_position_top", _(&torrent_handle::queue_position_top))
        .def("queue_position_bottom", _(&torrent_handle::queue_position_bottom))

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
        .def("resolve_countries", _(resolve_countries0))
        .def("resolve_countries", _(resolve_countries1))
#endif
        // deprecated
#ifndef TORRENT_NO_DEPRECATE
        .def("filter_piece", _(&torrent_handle::filter_piece))
        .def("is_piece_filtered", _(&torrent_handle::is_piece_filtered))
        .def("write_resume_data", _(&torrent_handle::write_resume_data))
#endif
        .def("add_piece", add_piece)
        .def("read_piece", _(&torrent_handle::read_piece))
        .def("piece_availability", piece_availability)
        .def("piece_priority", _(piece_priority0))
        .def("piece_priority", _(piece_priority1))
        .def("prioritize_pieces", prioritize_pieces)
        .def("piece_priorities", piece_priorities)
        .def("prioritize_files", prioritize_files)
        .def("file_priorities", file_priorities)
        .def("use_interface", &torrent_handle::use_interface)
        .def("save_resume_data", _(&torrent_handle::save_resume_data))
        .def("force_reannounce", _(force_reannounce0))
        .def("force_reannounce", force_reannounce)
        .def("scrape_tracker", _(&torrent_handle::scrape_tracker))
        .def("name", _(&torrent_handle::name))
        .def("set_upload_limit", _(&torrent_handle::set_upload_limit))
        .def("upload_limit", _(&torrent_handle::upload_limit))
        .def("set_download_limit", _(&torrent_handle::set_download_limit))
        .def("download_limit", _(&torrent_handle::download_limit))
        .def("set_sequential_download", _(&torrent_handle::set_sequential_download))
        .def("set_peer_upload_limit", set_peer_upload_limit)
        .def("set_peer_download_limit", set_peer_download_limit)
        .def("connect_peer", connect_peer)
        .def("set_ratio", _(&torrent_handle::set_ratio))
        .def("save_path", _(&torrent_handle::save_path))
        .def("set_max_uploads", _(&torrent_handle::set_max_uploads))
        .def("set_max_connections", _(&torrent_handle::set_max_connections))
        .def("set_tracker_login", _(&torrent_handle::set_tracker_login))
        .def("move_storage", _(move_storage0))
        .def("move_storage", _(move_storage1))
        .def("info_hash", _(&torrent_handle::info_hash))
        .def("force_recheck", _(&torrent_handle::force_recheck))
        .def("rename_file", _(rename_file0))
        .def("rename_file", _(rename_file1))
        ;
}
<|endoftext|>


<commit_before>//
// Copyright (C) 2013 Mateusz Łoskot <mateusz@loskot.net>
// Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
//
// This file is part of Qt Creator Boost.Build plugin project.
//
// This is free software; you can redistribute and/or modify it under
// the terms of the  GNU Lesser General Public License, Version 2.1
// as published by the Free Software Foundation.
// See accompanying file LICENSE.txt or copy at
// http://www.gnu.org/licenses/lgpl-2.1-standalone.html.
//
#include "bbbuildconfiguration.hpp"
#include "bbbuildstep.hpp"
#include "bbopenprojectwizard.hpp"
#include "bbproject.hpp"
#include "bbprojectfile.hpp"
#include "bbprojectmanager.hpp"
#include "bbprojectmanagerconstants.hpp"
#include "bbprojectnode.hpp"
#include "bbutility.hpp"
// Qt Creator
#include <app/app_version.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <coreplugin/generatedfile.h>
#include <coreplugin/mimedatabase.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cppprojects.h>
#include <cpptools/cpptoolsconstants.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/target.h>
#include <qtsupport/customexecutablerunconfiguration.h>
#include <utils/fileutils.h>
#include <utils/QtConcurrentTools>
// Qt
#include <QDir>
#include <QFileInfo>
#include <QMessageBox>

namespace BoostBuildProjectManager {
namespace Internal {

Project::Project(ProjectManager* manager, QString const& fileName)
    : manager_(manager)
    , filePath_(fileName)
    , projectFile_(new ProjectFile(this, filePath_)) // enables projectDirectory()
    , projectNode_(new ProjectNode(this, projectFile_))
{
    Q_ASSERT(manager_);
    Q_ASSERT(!filePath_.isEmpty());

    setProjectContext(Core::Context(Constants::PROJECT_CONTEXT));
    setProjectLanguages(Core::Context(ProjectExplorer::Constants::LANG_CXX));
#if defined(IDE_VERSION_MAJOR) && (IDE_VERSION_MAJOR == 3 && IDE_VERSION_MINOR > 0)
    setId(Constants::PROJECT_ID);
#endif

    QFileInfo const projectFileInfo(filePath_);
    QDir const projectDir(projectFileInfo.dir());
    projectName_ = defaultProjectName(filePath_);
    filesFilePath_ = QFileInfo(projectDir
        , filePath_ + QLatin1String(Constants::EXT_JAMFILE_FILES)).absoluteFilePath();
    includesFilePath_ = QFileInfo(projectDir
        , filePath_ + QLatin1String(Constants::EXT_JAMFILE_INCLUDES)).absoluteFilePath();

    projectNode_->setDisplayName(displayName());

    manager_->registerProject(this);

    // TODO: Add file watchers
    //projectFileWatcher_->addPath(projectFilePath);
    //connect(projectFileWatcher_, SIGNAL(fileChanged(QString)), this, SLOT(refresh()));

    BBPM_QDEBUG("created project: " << displayName() << " in " << projectDirectory());
}

Project::~Project()
{
    manager_->unregisterProject(this);
    delete projectNode_;
}

QString Project::displayName() const
{
    return projectName_;
}

#if defined(IDE_VERSION_MAJOR) && (IDE_VERSION_MAJOR == 3 && IDE_VERSION_MINOR == 0)
Core::Id Project::id() const
{
    return Core::Id(Constants::PROJECT_ID);
}
#endif

Core::IDocument* Project::document() const
{
    return projectFile_;
}

ProjectExplorer::IProjectManager* Project::projectManager() const
{
    return manager_;
}

ProjectExplorer::ProjectNode* Project::rootProjectNode() const
{
    return projectNode_;
}

QStringList Project::files(FilesMode fileMode) const
{
    // TODO: handle ExcludeGeneratedFiles, but what files exactly?
    //       *.qtcreator.files, *.qtcreator.includes and *.user?
    Q_UNUSED(fileMode);
    return files_;
}

QStringList Project::files() const
{
    return files(FilesMode::AllFiles);
}

QString Project::filesFilePath() const
{
    Q_ASSERT(!filesFilePath_.isEmpty());
    return filesFilePath_;
}

QString Project::includesFilePath() const
{
    Q_ASSERT(!includesFilePath_.isEmpty());
    return includesFilePath_;
}

bool Project::needsConfiguration() const
{
    // TODO: Does Boost.Build project require any configuration on loading?
    // - Kit selection
    // - build/stage directory
    // - targets listing
    // CMakeProjectManager seems to request configuration in fromMap()

    return false;
}

/*static*/
QString Project::defaultProjectName(QString const& fileName)
{
    QFileInfo const fileInfo(fileName);
    return fileInfo.absoluteDir().dirName();
}

/*static*/
QString Project::defaultBuildDirectory(QString const& top)
{
    Utils::FileName fn(Utils::FileName::fromString(defaultWorkingDirectory(top)));
    fn.appendPath(BBPM_C(BUILD_DIR_NAME));
    return fn.toString();
}

/*static*/
QString Project::defaultWorkingDirectory(QString const& top)
{
    // Accepts both, project file or project directory, as top.
    return ProjectExplorer::Project::projectDirectory(Utils::FileName::fromString(top)).toString();
}

void Project::setProjectName(QString const& name)
{
    if (projectName_ != name)
    {
        projectName_ = name;
        projectNode_->setDisplayName(projectName_);
        // TODO: signal?
    }
}

QVariantMap Project::toMap() const
{
    QVariantMap map(ProjectExplorer::Project::toMap());
    map.insert(QLatin1String(Constants::P_KEY_PROJECTNAME), projectName_);
    return map;
}

// This function is called at the very beginning to restore the settings
// from .user file, if there is any with previous settings stored.
bool Project::fromMap(QVariantMap const& map)
{
    BBPM_QDEBUG(displayName());
    QTC_ASSERT(projectNode_, return false);

    if (!ProjectExplorer::Project::fromMap(map))
        return false;

    QVariantMap extraValues(map);
    if (!extraValues.contains(BBPM_C(P_KEY_PROJECTNAME)))
        extraValues.insert(BBPM_C(P_KEY_PROJECTNAME), projectName_);
    setProjectName(map.value(BBPM_C(P_KEY_PROJECTNAME)).toString());

    // Check required auxiliary files, run wizard of necessary
    if (!QFileInfo(filesFilePath()).exists() || !QFileInfo(includesFilePath()).exists())
    {
        ProjectExplorer::Kit* defaultKit = ProjectExplorer::KitManager::defaultKit();
        Q_ASSERT(defaultKit);

        OpenProjectWizard wizard(this);
        if (!wizard.run(defaultKit->displayName(), extraValues))
            return false;

        QVariantMap outputValues = wizard.outputValues();
        setProjectName(outputValues.value(BBPM_C(P_KEY_PROJECTNAME)).toString());
    }

    // Set up active ProjectConfiguration (aka Target).
    // NOTE: Call setActiveBuildConfiguration when creating new build configurations.
    if (!activeTarget())
    {
        // Create project configuration from scratch

        // TODO: Map the Kit to Boost.Build toolset option value
        ProjectExplorer::Kit* defaultKit = ProjectExplorer::KitManager::defaultKit();
        Q_ASSERT(defaultKit);

        // Creates as many {Build|Run|Deploy}Configurations for as corresponding
        // factories report as available.
        // For example, BuildConfigurationFactory::availableBuilds => Debug and Release
        ProjectExplorer::Target* target = createTarget(defaultKit);
        QTC_ASSERT(target, return false);

        addTarget(target);
    }
    else
    {
        // Configure project from settings sorced from .user file
        // TODO: Do we need to handle anything from .user here? Do we need this case?
        BBPM_QDEBUG(displayName() << "has user file");
    }

    // Sanity check (taken from GenericProjectManager):
    // We need both a BuildConfiguration and a RunConfiguration!
    QList<ProjectExplorer::Target*> targetList = targets();
    foreach (ProjectExplorer::Target* t, targetList)
    {
        if (!t->activeBuildConfiguration())
        {
            removeTarget(t);
            continue;
        }
        if (!t->activeRunConfiguration())
            t->addRunConfiguration(new QtSupport::CustomExecutableRunConfiguration(t));
    }

    QTC_ASSERT(hasActiveBuildSettings(), return false);
    QTC_ASSERT(activeTarget() != 0, return false);

    // Trigger loading project tree and parsing sources
    refresh();

    return true;
}

void Project::refresh()
{
    QTC_ASSERT(QFileInfo(filesFilePath()).exists(), return);
    QTC_ASSERT(QFileInfo(includesFilePath()).exists(), return);

    QSet<QString> oldFileList;
    oldFileList = files_.toSet();

    // Parse project:
    // The manager does not parse Jamfile files.
    // Only generates and parses list of source files in Jamfile.${JAMFILE_FILES_EXT}
    QString const projectPath(projectDirectory().toString());
    filesRaw_ = Utility::readLines(filesFilePath());
    files_ = Utility::makeAbsolutePaths(projectPath, filesRaw_);

    QStringList includePaths =
        Utility::makeAbsolutePaths(projectPath,
            Utility::readLines(includesFilePath()));

    emit fileListChanged();

    projectNode_->refresh(oldFileList);

    // TODO: Does it make sense to move this to separate asynchronous task?
    // TODO: extract updateCppCodeModel
    CppTools::CppModelManager *modelmanager =
        CppTools::CppModelManager::instance();
    if (modelmanager) {
        CppTools::ProjectInfo pinfo = modelmanager->projectInfo(this);
        pinfo.clearProjectParts();

        CppTools::ProjectPartBuilder builder(pinfo);
        builder.setDisplayName(displayName());
        builder.setProjectFile(projectFilePath().toString());
        //builder.setDefines();	// TODO: waiting for Jamfile parser
        builder.setIncludePaths(QStringList() << projectDirectory().toString() << includePaths);

        const QList<Core::Id> languages = builder.createProjectPartsForFiles(files_);
        foreach (Core::Id language, languages)
            setProjectLanguage(language, true);

        cppModelFuture_.cancel();
        pinfo.finish();
        cppModelFuture_ = modelmanager->updateProjectInfo(pinfo);
    }
}

} // namespace Internal
} // namespace BoostBuildProjectManager
<commit_msg>Remove call of clearProjectParts<commit_after>//
// Copyright (C) 2013 Mateusz Łoskot <mateusz@loskot.net>
// Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
//
// This file is part of Qt Creator Boost.Build plugin project.
//
// This is free software; you can redistribute and/or modify it under
// the terms of the  GNU Lesser General Public License, Version 2.1
// as published by the Free Software Foundation.
// See accompanying file LICENSE.txt or copy at
// http://www.gnu.org/licenses/lgpl-2.1-standalone.html.
//
#include "bbbuildconfiguration.hpp"
#include "bbbuildstep.hpp"
#include "bbopenprojectwizard.hpp"
#include "bbproject.hpp"
#include "bbprojectfile.hpp"
#include "bbprojectmanager.hpp"
#include "bbprojectmanagerconstants.hpp"
#include "bbprojectnode.hpp"
#include "bbutility.hpp"
// Qt Creator
#include <app/app_version.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <coreplugin/generatedfile.h>
#include <coreplugin/mimedatabase.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cppprojects.h>
#include <cpptools/cpptoolsconstants.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/target.h>
#include <qtsupport/customexecutablerunconfiguration.h>
#include <utils/fileutils.h>
#include <utils/QtConcurrentTools>
// Qt
#include <QDir>
#include <QFileInfo>
#include <QMessageBox>

namespace BoostBuildProjectManager {
namespace Internal {

Project::Project(ProjectManager* manager, QString const& fileName)
    : manager_(manager)
    , filePath_(fileName)
    , projectFile_(new ProjectFile(this, filePath_)) // enables projectDirectory()
    , projectNode_(new ProjectNode(this, projectFile_))
{
    Q_ASSERT(manager_);
    Q_ASSERT(!filePath_.isEmpty());

    setProjectContext(Core::Context(Constants::PROJECT_CONTEXT));
    setProjectLanguages(Core::Context(ProjectExplorer::Constants::LANG_CXX));
#if defined(IDE_VERSION_MAJOR) && (IDE_VERSION_MAJOR == 3 && IDE_VERSION_MINOR > 0)
    setId(Constants::PROJECT_ID);
#endif

    QFileInfo const projectFileInfo(filePath_);
    QDir const projectDir(projectFileInfo.dir());
    projectName_ = defaultProjectName(filePath_);
    filesFilePath_ = QFileInfo(projectDir
        , filePath_ + QLatin1String(Constants::EXT_JAMFILE_FILES)).absoluteFilePath();
    includesFilePath_ = QFileInfo(projectDir
        , filePath_ + QLatin1String(Constants::EXT_JAMFILE_INCLUDES)).absoluteFilePath();

    projectNode_->setDisplayName(displayName());

    manager_->registerProject(this);

    // TODO: Add file watchers
    //projectFileWatcher_->addPath(projectFilePath);
    //connect(projectFileWatcher_, SIGNAL(fileChanged(QString)), this, SLOT(refresh()));

    BBPM_QDEBUG("created project: " << displayName() << " in " << projectDirectory());
}

Project::~Project()
{
    manager_->unregisterProject(this);
    delete projectNode_;
}

QString Project::displayName() const
{
    return projectName_;
}

#if defined(IDE_VERSION_MAJOR) && (IDE_VERSION_MAJOR == 3 && IDE_VERSION_MINOR == 0)
Core::Id Project::id() const
{
    return Core::Id(Constants::PROJECT_ID);
}
#endif

Core::IDocument* Project::document() const
{
    return projectFile_;
}

ProjectExplorer::IProjectManager* Project::projectManager() const
{
    return manager_;
}

ProjectExplorer::ProjectNode* Project::rootProjectNode() const
{
    return projectNode_;
}

QStringList Project::files(FilesMode fileMode) const
{
    // TODO: handle ExcludeGeneratedFiles, but what files exactly?
    //       *.qtcreator.files, *.qtcreator.includes and *.user?
    Q_UNUSED(fileMode);
    return files_;
}

QStringList Project::files() const
{
    return files(FilesMode::AllFiles);
}

QString Project::filesFilePath() const
{
    Q_ASSERT(!filesFilePath_.isEmpty());
    return filesFilePath_;
}

QString Project::includesFilePath() const
{
    Q_ASSERT(!includesFilePath_.isEmpty());
    return includesFilePath_;
}

bool Project::needsConfiguration() const
{
    // TODO: Does Boost.Build project require any configuration on loading?
    // - Kit selection
    // - build/stage directory
    // - targets listing
    // CMakeProjectManager seems to request configuration in fromMap()

    return false;
}

/*static*/
QString Project::defaultProjectName(QString const& fileName)
{
    QFileInfo const fileInfo(fileName);
    return fileInfo.absoluteDir().dirName();
}

/*static*/
QString Project::defaultBuildDirectory(QString const& top)
{
    Utils::FileName fn(Utils::FileName::fromString(defaultWorkingDirectory(top)));
    fn.appendPath(BBPM_C(BUILD_DIR_NAME));
    return fn.toString();
}

/*static*/
QString Project::defaultWorkingDirectory(QString const& top)
{
    // Accepts both, project file or project directory, as top.
    return ProjectExplorer::Project::projectDirectory(Utils::FileName::fromString(top)).toString();
}

void Project::setProjectName(QString const& name)
{
    if (projectName_ != name)
    {
        projectName_ = name;
        projectNode_->setDisplayName(projectName_);
        // TODO: signal?
    }
}

QVariantMap Project::toMap() const
{
    QVariantMap map(ProjectExplorer::Project::toMap());
    map.insert(QLatin1String(Constants::P_KEY_PROJECTNAME), projectName_);
    return map;
}

// This function is called at the very beginning to restore the settings
// from .user file, if there is any with previous settings stored.
bool Project::fromMap(QVariantMap const& map)
{
    BBPM_QDEBUG(displayName());
    QTC_ASSERT(projectNode_, return false);

    if (!ProjectExplorer::Project::fromMap(map))
        return false;

    QVariantMap extraValues(map);
    if (!extraValues.contains(BBPM_C(P_KEY_PROJECTNAME)))
        extraValues.insert(BBPM_C(P_KEY_PROJECTNAME), projectName_);
    setProjectName(map.value(BBPM_C(P_KEY_PROJECTNAME)).toString());

    // Check required auxiliary files, run wizard of necessary
    if (!QFileInfo(filesFilePath()).exists() || !QFileInfo(includesFilePath()).exists())
    {
        ProjectExplorer::Kit* defaultKit = ProjectExplorer::KitManager::defaultKit();
        Q_ASSERT(defaultKit);

        OpenProjectWizard wizard(this);
        if (!wizard.run(defaultKit->displayName(), extraValues))
            return false;

        QVariantMap outputValues = wizard.outputValues();
        setProjectName(outputValues.value(BBPM_C(P_KEY_PROJECTNAME)).toString());
    }

    // Set up active ProjectConfiguration (aka Target).
    // NOTE: Call setActiveBuildConfiguration when creating new build configurations.
    if (!activeTarget())
    {
        // Create project configuration from scratch

        // TODO: Map the Kit to Boost.Build toolset option value
        ProjectExplorer::Kit* defaultKit = ProjectExplorer::KitManager::defaultKit();
        Q_ASSERT(defaultKit);

        // Creates as many {Build|Run|Deploy}Configurations for as corresponding
        // factories report as available.
        // For example, BuildConfigurationFactory::availableBuilds => Debug and Release
        ProjectExplorer::Target* target = createTarget(defaultKit);
        QTC_ASSERT(target, return false);

        addTarget(target);
    }
    else
    {
        // Configure project from settings sorced from .user file
        // TODO: Do we need to handle anything from .user here? Do we need this case?
        BBPM_QDEBUG(displayName() << "has user file");
    }

    // Sanity check (taken from GenericProjectManager):
    // We need both a BuildConfiguration and a RunConfiguration!
    QList<ProjectExplorer::Target*> targetList = targets();
    foreach (ProjectExplorer::Target* t, targetList)
    {
        if (!t->activeBuildConfiguration())
        {
            removeTarget(t);
            continue;
        }
        if (!t->activeRunConfiguration())
            t->addRunConfiguration(new QtSupport::CustomExecutableRunConfiguration(t));
    }

    QTC_ASSERT(hasActiveBuildSettings(), return false);
    QTC_ASSERT(activeTarget() != 0, return false);

    // Trigger loading project tree and parsing sources
    refresh();

    return true;
}

void Project::refresh()
{
    QTC_ASSERT(QFileInfo(filesFilePath()).exists(), return);
    QTC_ASSERT(QFileInfo(includesFilePath()).exists(), return);

    QSet<QString> oldFileList;
    oldFileList = files_.toSet();

    // Parse project:
    // The manager does not parse Jamfile files.
    // Only generates and parses list of source files in Jamfile.${JAMFILE_FILES_EXT}
    QString const projectPath(projectDirectory().toString());
    filesRaw_ = Utility::readLines(filesFilePath());
    files_ = Utility::makeAbsolutePaths(projectPath, filesRaw_);

    QStringList includePaths =
        Utility::makeAbsolutePaths(projectPath,
            Utility::readLines(includesFilePath()));

    emit fileListChanged();

    projectNode_->refresh(oldFileList);

    // TODO: Does it make sense to move this to separate asynchronous task?
    // TODO: extract updateCppCodeModel
    CppTools::CppModelManager *modelmanager =
        CppTools::CppModelManager::instance();
    if (modelmanager) {
        CppTools::ProjectInfo pinfo = modelmanager->projectInfo(this);

        CppTools::ProjectPartBuilder builder(pinfo);
        builder.setDisplayName(displayName());
        builder.setProjectFile(projectFilePath().toString());
        //builder.setDefines();	// TODO: waiting for Jamfile parser
        builder.setIncludePaths(QStringList() << projectDirectory().toString() << includePaths);

        const QList<Core::Id> languages = builder.createProjectPartsForFiles(files_);
        foreach (Core::Id language, languages)
            setProjectLanguage(language, true);

        cppModelFuture_.cancel();
        pinfo.finish();
        cppModelFuture_ = modelmanager->updateProjectInfo(pinfo);
    }
}

} // namespace Internal
} // namespace BoostBuildProjectManager
<|endoftext|>


<commit_before>#include <random>

#include "rank_filter.hxx"

int main(int argc, char** argv)
{
    std::random_device rd;
    std::mt19937 gen(rd());

    std::normal_distribution<float> dist;

    vigra::MultiArray<3, float>::difference_type shape(100, 101, 102);
    vigra::MultiArray<3, float> input(shape);
    vigra::MultiArray<3, float> output(shape);

    for (unsigned long i_0 = 0; i_0 < shape[0]; i_0++)
    {
        for (unsigned long i_1 = 0; i_1 < shape[1]; i_1++)
        {
            for (unsigned long i_2 = 0; i_2 < shape[2]; i_2++)
            {
                input(i_0, i_1, i_2) = dist(gen);
            }
        }
    }

    lineRankOrderFilter(input, output, 800L, 0.5, 0);

    return(0);
}
<commit_msg>src/benchmark_rank_filter.cxx: Fix window size to be reasonable.<commit_after>#include <random>

#include "rank_filter.hxx"

int main(int argc, char** argv)
{
    std::random_device rd;
    std::mt19937 gen(rd());

    std::normal_distribution<float> dist;

    vigra::MultiArray<3, float>::difference_type shape(100, 101, 102);
    vigra::MultiArray<3, float> input(shape);
    vigra::MultiArray<3, float> output(shape);

    for (unsigned long i_0 = 0; i_0 < shape[0]; i_0++)
    {
        for (unsigned long i_1 = 0; i_1 < shape[1]; i_1++)
        {
            for (unsigned long i_2 = 0; i_2 < shape[2]; i_2++)
            {
                input(i_0, i_1, i_2) = dist(gen);
            }
        }
    }

    lineRankOrderFilter(input, output, 25L, 0.5, 0);

    return(0);
}
<|endoftext|>


<commit_before>/** @file
 *
 * @ingroup spatdiflib
 *
 * @brief
 *
 * @details
 *
 * @authors Chikashi Miyama, Trond Lossius
 *
 * @copyright Copyright (C) 2013 - 2014 Zurich University of the Arts, Institute for Computer Music and Sound Technology @n
 * This code is licensed under the terms of the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "sdConst.h"
#include "sdOSCResponder.h"
#include <vector>
#include <sstream>

using namespace std;

sdOSCResponder::sdOSCResponder(void){
    queryTime = 0.0;
    writeTime = 0.0;
}

sdOSCResponder::sdOSCResponder(sdScene *scene){
    sdOSCResponder::scene =scene;
    sdOSCResponder();
}

vector<string> sdOSCResponder::splitString(const string &str){
    vector<string> res;
    size_t current = 0, found;
    while((found = str.find_first_of('/', current)) != string::npos){
        res.push_back(string(str, current, found - current));
        current = found + 1;
    }
    res.push_back(string(str, current, str.size() - current));
    return res;
}

bool sdOSCResponder::checkNumberOfArguments(int expectedNumber, int actualNumber, string command, string &errorMessage){
    string mes;
    if (actualNumber == expectedNumber){
        return true;
    }else if (actualNumber < expectedNumber) {
        mes = "too few arguments";
    }else if(actualNumber > expectedNumber){
        mes = "too many arguments";
    }
    errorMessage = "/spatdif/error";
    return false;
}

string sdOSCResponder::forwardOSCMessage(string oscMessage, double time){
    setQueryTime(time);
    return forwardOSCMessage(oscMessage);
}

string sdOSCResponder::forwardOSCMessage(string oscMessage){

// interpret
    string element, command, errorMessage;
    vector<string> arguments;
    istringstream iss(oscMessage);
    int count = 0;
    EKind kd;

    // analyze
    while(iss.good()){
        iss >> element;

        switch(count){
            case 0:{
                //address pattern
                if (element[0] != '/') {
                    cout << "sdOSCReponder Error: The first element of incoming OSC Message is not an address pattern." << endl;
                    return NULL;
                }
                //split into parts
                vector <string>ads = splitString(element);
                ads.erase (ads.begin());

                if (ads.size() < 2 ) {
                    cout << "sdOSCResponder Error: The address pattern consists of two few elements." << endl;
                    return NULL;
                }

                if(ads[0] != "spatdifcmd"){
                    cout << "sdOSCResponder Error: The address pattern of the received message does not begin with \"spatdifcmd\"." << endl;
                    return NULL;
                }

                command = ads[1];

                break;
            }
            case 1:{
                if (element[0] == ',') {  // with type tag, just ignore
                    iss >> element;
                }
            }
            default:{
                arguments.push_back(element); // copy all arguments to vector
            }
        }
        count++;
    }

    // interpet the command

    if( command == "setQueryTime"){

        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage))
            return errorMessage;

        setQueryTime(stringToDouble(arguments[0]));

    }else if(command == "getQueryTime"){

        if(!checkNumberOfArguments( 0, arguments.size(), command, errorMessage))
            return errorMessage;

        return "/spatdif/queryTime d " + doubleToString(getQueryTime());

    }else if(command == "setWriteTime"){

        if(!checkNumberOfArguments( 1, arguments.size(), command, errorMessage))
            return errorMessage;

        setWriteTime(stringToDouble(arguments[0]));

    }else if(command == "getWriteTime"){
        if(!checkNumberOfArguments( 0, arguments.size(), command, errorMessage)){
            return errorMessage;
        }
        return "/spatdif/writeTime d " + doubleToString(getWriteTime());

    }else if(command == "setPosition"){
        if(!checkNumberOfArguments( 4, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        double pos[3];
        pos[0] = stringToDouble(arguments[1]);
        pos[1] = stringToDouble(arguments[2]);
        pos[2] = stringToDouble(arguments[3]);
        scene->setValue(arguments[0], writeTime, SD_POSITION, (void*)pos);

    }else if(command == "getPosition"){

        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        sdEntityCore* entity =  scene->getEntity(arguments[0]);
        if (!entity) {
            return "/spatdif/error";
        }
        sdEventCore* event = (sdEventCore*)entity->getEvent(queryTime, SD_POSITION);
        if(!event){
            return "/spatdif/error";
        }
        string returnStr = "/spatdif/source/";
        return  returnStr + entity->getName() + "/position ddd " + event->getValueAsString();

    }else if(command == "setOrientation"){
        if(!checkNumberOfArguments( 4, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        double ori[3];
        ori[0] = stringToDouble(arguments[1]);
        ori[1] = stringToDouble(arguments[2]);
        ori[2] = stringToDouble(arguments[3]);
        scene->setValue(arguments[0], writeTime, SD_ORIENTATION, (void*)ori);

    }else if(command == "getOrientation"){

        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        sdEntityCore* entity =  scene->getEntity(arguments[0]);
        if (!entity) {
            return "/spatdif/error";
        }
        sdEventCore* event = (sdEventCore*)entity->getEvent(queryTime, SD_ORIENTATION);
        if(!event){
            return "/spatdif/error";
        }
        string returnStr = "/spatdif/source/";
        return  returnStr + entity->getName() + "/orientation ddd " + event->getValueAsString();

    }else if(command == "setPresent"){
        if(!checkNumberOfArguments( 2, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        bool present = stringToBool(arguments[1]);
        scene->setValue(arguments[0], writeTime, SD_PRESENT, (void*)&present);

    }else if(command == "getPresent"){

        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        sdEntityCore* entity =  scene->getEntity(arguments[0]);
        if (!entity) {
            return "/spatdif/error";
        }
        sdEventCore* event = (sdEventCore*)entity->getEvent(queryTime, SD_PRESENT);
        if(!event){
            return "/spatdif/error";
        }
        return "/spatdif/source/" + entity->getName() + "/present s " + event->getValueAsString();

    }else if(command == "getNumberOfEntities"){

        if(!checkNumberOfArguments( 0, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        return "/spatdif/source/numberOfEntities i " + intToString(scene->getNumberOfEntities());

    }else if(command == "getEntityNames"){

        if(!checkNumberOfArguments( 0, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        int num = scene->getNumberOfEntities();
        string tt, names;
        for(int i = 0; i< num; i++){
            tt += 's';
            names += scene->getEntityName(i);
            names += ' ';
        }
        return "/spatdif/source/entityNames " + tt + ' ' + names;

    }else if(command == "getOrdering"){
        if(!checkNumberOfArguments( 0, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        return "/spatdif/ordering s " + scene->getOrderingAsString();

    }else if(command == "setOrdering"){
        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        if(arguments[0] == "track"){
            scene->setOrdering(SD_TRACK);
        }else if(arguments[0] == "time"){
            scene->setOrdering(SD_TIME);
        }else{
            return "/spatdif/error";
        }
    }else if(command == "addEntity"){
        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        scene->addEntity(arguments[0]);
    }else if(command == "removeEntity"){
        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        scene->removeEntity(arguments[0]);

    }else if(command == "removeAllEntities"){
        if(!checkNumberOfArguments( 0, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        scene->removeAllEntities();
    }

    return "/spatdif/success";

}

<commit_msg>added 6 more commands<commit_after>/** @file
 *
 * @ingroup spatdiflib
 *
 * @brief
 *
 * @details
 *
 * @authors Chikashi Miyama, Trond Lossius
 *
 * @copyright Copyright (C) 2013 - 2014 Zurich University of the Arts, Institute for Computer Music and Sound Technology @n
 * This code is licensed under the terms of the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "sdConst.h"
#include "sdOSCResponder.h"
#include <vector>
#include <sstream>

using namespace std;

sdOSCResponder::sdOSCResponder(void){
    queryTime = 0.0;
    writeTime = 0.0;
}

sdOSCResponder::sdOSCResponder(sdScene *scene){
    sdOSCResponder::scene =scene;
    sdOSCResponder();
}

vector<string> sdOSCResponder::splitString(const string &str){
    vector<string> res;
    size_t current = 0, found;
    while((found = str.find_first_of('/', current)) != string::npos){
        res.push_back(string(str, current, found - current));
        current = found + 1;
    }
    res.push_back(string(str, current, str.size() - current));
    return res;
}

bool sdOSCResponder::checkNumberOfArguments(int expectedNumber, int actualNumber, string command, string &errorMessage){
    string mes;
    if (actualNumber == expectedNumber){
        return true;
    }else if (actualNumber < expectedNumber) {
        mes = "too few arguments";
    }else if(actualNumber > expectedNumber){
        mes = "too many arguments";
    }
    errorMessage = "/spatdif/error";
    return false;
}

string sdOSCResponder::forwardOSCMessage(string oscMessage, double time){
    setQueryTime(time);
    return forwardOSCMessage(oscMessage);
}

string sdOSCResponder::forwardOSCMessage(string oscMessage){

// interpret
    string element, command, errorMessage;
    vector<string> arguments;
    istringstream iss(oscMessage);
    int count = 0;
    EKind kd;

    // analyze
    while(iss.good()){
        iss >> element;

        switch(count){
            case 0:{
                //address pattern
                if (element[0] != '/') {
                    cout << "sdOSCReponder Error: The first element of incoming OSC Message is not an address pattern." << endl;
                    return NULL;
                }
                //split into parts
                vector <string>ads = splitString(element);
                ads.erase (ads.begin());

                if (ads.size() < 2 ) {
                    cout << "sdOSCResponder Error: The address pattern consists of two few elements." << endl;
                    return NULL;
                }

                if(ads[0] != "spatdifcmd"){
                    cout << "sdOSCResponder Error: The address pattern of the received message does not begin with \"spatdifcmd\"." << endl;
                    return NULL;
                }

                command = ads[1];

                break;
            }
            case 1:{
                if (element[0] == ',') {  // with type tag, just ignore
                    iss >> element;
                }
            }
            default:{
                arguments.push_back(element); // copy all arguments to vector
            }
        }
        count++;
    }

    // interpet the command

    if( command == "setQueryTime"){

        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage))
            return errorMessage;

        setQueryTime(stringToDouble(arguments[0]));

    }else if(command == "getQueryTime"){

        if(!checkNumberOfArguments( 0, arguments.size(), command, errorMessage))
            return errorMessage;

        return "/spatdif/queryTime d " + doubleToString(getQueryTime());

    }else if(command == "setWriteTime"){

        if(!checkNumberOfArguments( 1, arguments.size(), command, errorMessage))
            return errorMessage;

        setWriteTime(stringToDouble(arguments[0]));

    }else if(command == "getWriteTime"){
        if(!checkNumberOfArguments( 0, arguments.size(), command, errorMessage)){
            return errorMessage;
        }
        return "/spatdif/writeTime d " + doubleToString(getWriteTime());

    }else if(command == "setPosition"){
        if(!checkNumberOfArguments( 4, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        double pos[3];
        pos[0] = stringToDouble(arguments[1]);
        pos[1] = stringToDouble(arguments[2]);
        pos[2] = stringToDouble(arguments[3]);
        scene->setValue(arguments[0], writeTime, SD_POSITION, (void*)pos);

    }else if(command == "getPosition"){

        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        sdEntityCore* entity =  scene->getEntity(arguments[0]);
        if (!entity) {
            return "/spatdif/error";
        }
        sdEventCore* event = (sdEventCore*)entity->getEvent(queryTime, SD_POSITION);
        if(!event){
            return "/spatdif/error";
        }
        string returnStr = "/spatdif/source/";
        return  returnStr + entity->getName() + "/position ddd " + event->getValueAsString();

    }else if(command == "getNextPosition"){
        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        sdEntityCore* entity =  scene->getEntity(arguments[0]);
        if (!entity) {
            return "/spatdif/error";
        }
        sdEventCore* event = (sdEventCore*)entity->getNextEvent(queryTime, SD_POSITION);
        if(!event){
            return "/spatdif/error";
        }
        string returnStr = "/spatdif/source/";
        return  returnStr + entity->getName() + "/position dddd " + event->getTimeAsString() + ' ' + event->getValueAsString();

    }else if(command == "getPreviousPosition"){
        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        sdEntityCore* entity =  scene->getEntity(arguments[0]);
        if (!entity) {
            return "/spatdif/error";
        }
        sdEventCore* event = (sdEventCore*)entity->getPreviousEvent(queryTime, SD_POSITION);
        if(!event){
            return "/spatdif/error";
        }
        string returnStr = "/spatdif/source/";
        return  returnStr + entity->getName() + "/position dddd " + event->getTimeAsString() + ' ' + event->getValueAsString();

    }
    else if(command == "setOrientation"){
        if(!checkNumberOfArguments( 4, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        double ori[3];
        ori[0] = stringToDouble(arguments[1]);
        ori[1] = stringToDouble(arguments[2]);
        ori[2] = stringToDouble(arguments[3]);
        scene->setValue(arguments[0], writeTime, SD_ORIENTATION, (void*)ori);

    }else if(command == "getOrientation"){

        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        sdEntityCore* entity =  scene->getEntity(arguments[0]);
        if (!entity) {
            return "/spatdif/error";
        }
        sdEventCore* event = (sdEventCore*)entity->getEvent(queryTime, SD_ORIENTATION);
        if(!event){
            return "/spatdif/error";
        }
        string returnStr = "/spatdif/source/";
        return  returnStr + entity->getName() + "/orientation ddd " + event->getValueAsString();

    }else if(command == "getNextOrientation"){
        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        sdEntityCore* entity =  scene->getEntity(arguments[0]);
        if (!entity) {
            return "/spatdif/error";
        }
        sdEventCore* event = (sdEventCore*)entity->getNextEvent(queryTime, SD_ORIENTATION);
        if(!event){
            return "/spatdif/error";
        }
        string returnStr = "/spatdif/source/";
        return  returnStr + entity->getName() + "/orientation dddd " + event->getTimeAsString() + ' '+ event->getValueAsString();

    }else if(command == "getPreviousOrientation"){
        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        sdEntityCore* entity =  scene->getEntity(arguments[0]);
        if (!entity) {
            return "/spatdif/error";
        }
        sdEventCore* event = (sdEventCore*)entity->getPreviousEvent(queryTime, SD_ORIENTATION);
        if(!event){
            return "/spatdif/error";
        }
        string returnStr = "/spatdif/source/";
        return  returnStr + entity->getName() + "/orientation dddd " + event->getTimeAsString() + ' ' + event->getValueAsString();

    }
else if(command == "setPresent"){
        if(!checkNumberOfArguments( 2, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        bool present = stringToBool(arguments[1]);
        scene->setValue(arguments[0], writeTime, SD_PRESENT, (void*)&present);

    }else if(command == "getPresent"){

        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        sdEntityCore* entity =  scene->getEntity(arguments[0]);
        if (!entity) {
            return "/spatdif/error";
        }
        sdEventCore* event = (sdEventCore*)entity->getEvent(queryTime, SD_PRESENT);
        if(!event){
            return "/spatdif/error";
        }
        return "/spatdif/source/" + entity->getName() + "/present s " + event->getValueAsString();

    }else if(command == "getNextPresent"){

        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        sdEntityCore* entity =  scene->getEntity(arguments[0]);
        if (!entity) {
            return "/spatdif/error";
        }
        sdEventCore* event = (sdEventCore*)entity->getNextEvent(queryTime, SD_PRESENT);
        if(!event){
            return "/spatdif/error";
        }
        return "/spatdif/source/" + entity->getName() + "/present ds " + event->getTimeAsString() + ' ' + event->getValueAsString();

    }else if(command == "getPreviousPresent"){

        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        sdEntityCore* entity =  scene->getEntity(arguments[0]);
        if (!entity) {
            return "/spatdif/error";
        }
        sdEventCore* event = (sdEventCore*)entity->getPreviousEvent(queryTime, SD_PRESENT);
        if(!event){
            return "/spatdif/error";
        }
        return "/spatdif/source/" + entity->getName() + "/present ds " + event->getTimeAsString() + ' ' + event->getValueAsString();

    }else if(command == "getNumberOfEntities"){

        if(!checkNumberOfArguments( 0, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        return "/spatdif/source/numberOfEntities i " + intToString(scene->getNumberOfEntities());

    }else if(command == "getEntityNames"){

        if(!checkNumberOfArguments( 0, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        int num = scene->getNumberOfEntities();
        string tt, names;
        for(int i = 0; i< num; i++){
            tt += 's';
            names += scene->getEntityName(i);
            names += ' ';
        }
        return "/spatdif/source/entityNames " + tt + ' ' + names;

    }else if(command == "getOrdering"){
        if(!checkNumberOfArguments( 0, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        return "/spatdif/ordering s " + scene->getOrderingAsString();

    }else if(command == "setOrdering"){
        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }

        if(arguments[0] == "track"){
            scene->setOrdering(SD_TRACK);
        }else if(arguments[0] == "time"){
            scene->setOrdering(SD_TIME);
        }else{
            return "/spatdif/error";
        }
    }else if(command == "addEntity"){
        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        scene->addEntity(arguments[0]);
    }else if(command == "removeEntity"){
        if(!checkNumberOfArguments( 1, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        scene->removeEntity(arguments[0]);

    }else if(command == "removeAllEntities"){
        if(!checkNumberOfArguments( 0, arguments.size() ,command, errorMessage)){
            return errorMessage;
        }
        scene->removeAllEntities();
    }

    return "/spatdif/success";

}

<|endoftext|>