<commit_before>/*
 * Embedded binary accessors
 *
 * Copyright (c) 2015 Daniel Verkamp
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "narf/embed.h"

#include <zlib.h>
#include <stdio.h>

bool narf::embed::uncompress(void* dst, size_t dstSize, const void* src, size_t srcSize) {
	z_stream st;

	st.next_in = static_cast<z_const Bytef*>(const_cast<void*>(src));
	st.avail_in = static_cast<uInt>(srcSize);

	st.next_out = static_cast<Bytef*>(dst);
	st.avail_out = static_cast<uInt>(dstSize);

	st.zalloc = nullptr;
	st.zfree = nullptr;

	if (::inflateInit2(&st, 32) != Z_OK) { // 32 = autodetect zlib/gzip
		return false;
	}

	if (::inflate(&st, Z_FINISH) != Z_STREAM_END) {
		return false;
	}

	if (st.total_out != dstSize) {
		return false;
	}

	return true;
}
<commit_msg>embed: remove use of z_const<commit_after>/*
 * Embedded binary accessors
 *
 * Copyright (c) 2015 Daniel Verkamp
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "narf/embed.h"

#include <zlib.h>
#include <stdio.h>

bool narf::embed::uncompress(void* dst, size_t dstSize, const void* src, size_t srcSize) {
	z_stream st;

	st.next_in = static_cast<Bytef*>(const_cast<void*>(src));
	st.avail_in = static_cast<uInt>(srcSize);

	st.next_out = static_cast<Bytef*>(dst);
	st.avail_out = static_cast<uInt>(dstSize);

	st.zalloc = nullptr;
	st.zfree = nullptr;

	if (::inflateInit2(&st, 32) != Z_OK) { // 32 = autodetect zlib/gzip
		return false;
	}

	if (::inflate(&st, Z_FINISH) != Z_STREAM_END) {
		return false;
	}

	if (st.total_out != dstSize) {
		return false;
	}

	return true;
}
<|endoftext|>


<commit_before>#include "net/telnet.h"

#include <arpa/telnet.h>

static constexpr std::size_t telnet_option_count = 256;

struct rethinkmud::net::connections::telnet::telnet_info
{
    // What we do, and don't do
    bool options[telnet_option_count] = { false };

    // Options we have sent and are waiting for reply on
    bool sent_will[telnet_option_count] = { false };
    bool sent_wont[telnet_option_count] = { false };
    bool sent_do[telnet_option_count] = { false };
    bool sent_dont[telnet_option_count] = { false };
};

void rethinkmud::net::connections::telnet::telnet_info_deleter::operator()(telnet_info* info)
{
    delete info;
}

void rethinkmud::net::connections::telnet::start()
{
    std::clog << "Starting telnet connection\n";
    info_.reset(new telnet_info);

    tcp::start();
}

void rethinkmud::net::connections::telnet::input(std::vector<char> data)
{
    // Parse the input for telnet command sequence
    // Copy the non-telnet data to a new container
    // For now we assume that all sequences are complete

    std::string input;

    for (auto i = std::begin(data); i != std::end(data); ++i)
    {
        if (static_cast<unsigned char>(*i) == IAC)
        {
            // TODO: Handle the telnet stuff
        }
        else
            input += *i;
    }

    write("You wrote: " + input);

    // TODO: Split the input into lines, and add each line into a queue
}

void rethinkmud::net::connections::telnet::send_option(uint8_t command, uint8_t option)
{
    uint8_t const data[] = {
        IAC,
        command,
        option
    };
    write(data, sizeof(data));
}

void rethinkmud::net::connections::telnet::send_do(uint8_t option)
{
    if (!info_->sent_do[option])
    {
        send_option(DO, option);
        info_->sent_do[option] = true;
    }
}

void rethinkmud::net::connections::telnet::send_dont(uint8_t option)
{
    if (!info_->sent_dont[option])
    {
        send_option(DONT, option);
        info_->sent_dont[option] = true;
    }
}

void rethinkmud::net::connections::telnet::send_will(uint8_t option)
{
    if (!info_->sent_will[option])
    {
        send_option(WILL, option);
        info_->sent_will[option] = true;
    }
}

void rethinkmud::net::connections::telnet::send_wont(uint8_t option)
{
    if (!info_->sent_wont[option])
    {
        send_option(WONT, option);
        info_->sent_wont[option] = true;
    }
}

void rethinkmud::net::connections::telnet::echo_on()
{
    send_wont(ECHO);
    send_do(ECHO);
}

void rethinkmud::net::connections::telnet::echo_off()
{
    send_will(ECHO);
    send_dont(ECHO);
}
<commit_msg>Simple command handling for debugging purposes<commit_after>#include "net/telnet.h"

#include <arpa/telnet.h>

static constexpr std::size_t telnet_option_count = 256;

struct rethinkmud::net::connections::telnet::telnet_info
{
    // What we do, and don't do
    bool options[telnet_option_count] = { false };

    // Options we have sent and are waiting for reply on
    bool sent_will[telnet_option_count] = { false };
    bool sent_wont[telnet_option_count] = { false };
    bool sent_do[telnet_option_count] = { false };
    bool sent_dont[telnet_option_count] = { false };
};

void rethinkmud::net::connections::telnet::telnet_info_deleter::operator()(telnet_info* info)
{
    delete info;
}

void rethinkmud::net::connections::telnet::start()
{
    std::clog << "Starting telnet connection\n";
    info_.reset(new telnet_info);

    tcp::start();
}

void rethinkmud::net::connections::telnet::input(std::vector<char> data)
{
    // Parse the input for telnet command sequence
    // Copy the non-telnet data to a new container
    // For now we assume that all sequences are complete

    std::string input;

    for (auto i = std::begin(data); i != std::end(data); ++i)
    {
        if (static_cast<unsigned char>(*i) == IAC)
        {
            // TODO: Handle the telnet stuff
        }
        else
            input += *i;
    }

    if (input == "echo off\r\n")
        echo_off();
    else if (input == "echo on\r\n")
        echo_on();
    else
        write("You wrote: " + input);

    // TODO: Split the input into lines, and add each line into a queue
}

void rethinkmud::net::connections::telnet::send_option(uint8_t command, uint8_t option)
{
    uint8_t const data[] = {
        IAC,
        command,
        option
    };
    write(data, sizeof(data));
}

void rethinkmud::net::connections::telnet::send_do(uint8_t option)
{
    if (!info_->sent_do[option])
    {
        send_option(DO, option);
        info_->sent_do[option] = true;
    }
}

void rethinkmud::net::connections::telnet::send_dont(uint8_t option)
{
    if (!info_->sent_dont[option])
    {
        send_option(DONT, option);
        info_->sent_dont[option] = true;
    }
}

void rethinkmud::net::connections::telnet::send_will(uint8_t option)
{
    if (!info_->sent_will[option])
    {
        send_option(WILL, option);
        info_->sent_will[option] = true;
    }
}

void rethinkmud::net::connections::telnet::send_wont(uint8_t option)
{
    if (!info_->sent_wont[option])
    {
        send_option(WONT, option);
        info_->sent_wont[option] = true;
    }
}

void rethinkmud::net::connections::telnet::echo_on()
{
    send_wont(TELOPT_ECHO);
    send_do(TELOPT_ECHO);
}

void rethinkmud::net::connections::telnet::echo_off()
{
    send_will(TELOPT_ECHO);
    send_dont(TELOPT_ECHO);
}
<|endoftext|>


<commit_before>// $RCSfile: $
// $Revision: $ $Date: $
// Auth: Samson Bonfante (bonfante@steptools.com)
//
// Copyright (c) 1991-2016 by STEP Tools Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "nodeFinder.h"
#include "nodeUtils.h"
Finder *Finder::_singleton = nullptr;

NAN_METHOD(Finder::New)
{
	if (info.IsConstructCall())
	{
		if (!info[0]->IsUndefined())
		{
			return;
		}
		if (_singleton == nullptr)
			_singleton = new Finder();
		_singleton->Wrap(info.This());
		info.GetReturnValue().Set(info.This());
	}
	else
	{
		return;
	}
}

NAN_MODULE_INIT(Finder::Init)
{
	v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
	tpl->SetClassName(Nan::New("Finder").ToLocalChecked());
	tpl->InstanceTemplate()->SetInternalFieldCount(1);

	Nan::SetPrototypeMethod(tpl, "GetFeatureID", GetFeatureID);
	Nan::SetPrototypeMethod(tpl, "GetMainWorkplan", GetMainWorkplan);
	Nan::SetPrototypeMethod(tpl, "OpenProject", OpenProject);
	Nan::SetPrototypeMethod(tpl, "SaveAsP21", SaveAsP21);
	Nan::SetPrototypeMethod(tpl, "SaveAsModules", SaveAsModules);

	constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked());
	Nan::Set(target, Nan::New("Finder").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked());
}

NAN_METHOD(Finder::GetMainWorkplan) {
	Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) //Throw Exception
		return;
	if (!info[0]->IsUndefined()) //Function shouldn't get any arguments.
		return;
	int rtn = 0;
	int sz;
	if (!find->_find->main(rtn, sz))
		return;//Error in c++ code
	info.GetReturnValue().Set(rtn);
	return;
}

NAN_METHOD(Finder::OpenProject) {
	Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) //Throw Exception
		return;
	if (info.Length() != 1) //Function should get one argument.
		return;
	if (!info[0]->IsString())
		return;
	char * fname = 0;
	ssize_t fnamelen = v8StringToChar(info[0], fname);
	if(!find->_find->search(fname)) //TODO: Handle Error.
		return;
	return; //Success finding, return.
}

NAN_METHOD(Finder::SaveAsP21)
{
	Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) //Throw Exception
		return;

	if (!info[0]->IsUndefined())
		return;

	if (!info[0]->IsString())
		return;

	v8::Local<v8::String> file_name = info[0]->ToString();
	char* file_name_utf8;
	v8StringToChar(file_name, file_name_utf8);

	if (!find->_find->save_file(file_name_utf8, false)) //Throw Exception
		return;
}
<commit_msg>Finder::SaveAsModules Implementation Added<commit_after>// $RCSfile: $
// $Revision: $ $Date: $
// Auth: Samson Bonfante (bonfante@steptools.com)
//
// Copyright (c) 1991-2016 by STEP Tools Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "nodeFinder.h"
#include "nodeUtils.h"
Finder *Finder::_singleton = nullptr;

NAN_METHOD(Finder::New)
{
	if (info.IsConstructCall())
	{
		if (!info[0]->IsUndefined())
		{
			return;
		}
		if (_singleton == nullptr)
			_singleton = new Finder();
		_singleton->Wrap(info.This());
		info.GetReturnValue().Set(info.This());
	}
	else
	{
		return;
	}
}

NAN_MODULE_INIT(Finder::Init)
{
	v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
	tpl->SetClassName(Nan::New("Finder").ToLocalChecked());
	tpl->InstanceTemplate()->SetInternalFieldCount(1);

	Nan::SetPrototypeMethod(tpl, "GetFeatureID", GetFeatureID);
	Nan::SetPrototypeMethod(tpl, "GetMainWorkplan", GetMainWorkplan);
	Nan::SetPrototypeMethod(tpl, "OpenProject", OpenProject);
	Nan::SetPrototypeMethod(tpl, "SaveAsP21", SaveAsP21);
	Nan::SetPrototypeMethod(tpl, "SaveAsModules", SaveAsModules);

	constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked());
	Nan::Set(target, Nan::New("Finder").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked());
}

NAN_METHOD(Finder::GetMainWorkplan) {
	Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) //Throw Exception
		return;
	if (!info[0]->IsUndefined()) //Function shouldn't get any arguments.
		return;
	int rtn = 0;
	int sz;
	if (!find->_find->main(rtn, sz))
		return;//Error in c++ code
	info.GetReturnValue().Set(rtn);
	return;
}

NAN_METHOD(Finder::OpenProject) {
	Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) //Throw Exception
		return;
	if (info.Length() != 1) //Function should get one argument.
		return;
	if (!info[0]->IsString())
		return;
	char * fname = 0;
	ssize_t fnamelen = v8StringToChar(info[0], fname);
	if(!find->_find->search(fname)) //TODO: Handle Error.
		return;
	return; //Success finding, return.
}

NAN_METHOD(Finder::SaveAsModules)
{
    Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (find == 0) //Throw Exception
	return;

    if (!info[0]->IsUndefined())
	return;

    if (!info[0]->IsString())
	return;

    v8::Local<v8::String> file_name = info[0]->ToString();
    char* file_name_utf8;
    v8StringToChar(file_name, file_name_utf8);

    if (!find->_find->save_file(file_name_utf8, true)) //Throw Exception
	return;
}

NAN_METHOD(Finder::SaveAsP21)
{
	Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) //Throw Exception
		return;

	if (!info[0]->IsUndefined())
		return;

	if (!info[0]->IsString())
		return;

	v8::Local<v8::String> file_name = info[0]->ToString();
	char* file_name_utf8;
	v8StringToChar(file_name, file_name_utf8);

	if (!find->_find->save_file(file_name_utf8, false)) //Throw Exception
		return;
}
<|endoftext|>


<commit_before>// $RCSfile: $
// $Revision: $ $Date: $
// Auth: Samson Bonfante (bonfante@steptools.com)
//
// Copyright (c) 1991-2016 by STEP Tools Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "nodeFinder.h"
#include "nodeUtils.h"
Finder *Finder::_singleton = nullptr;

NAN_METHOD(Finder::New)
{
	if (info.IsConstructCall())
	{
		if (!info[0]->IsUndefined())
		{
			return;
		}
		if (_singleton == nullptr)
			_singleton = new Finder();
		_singleton->Wrap(info.This());
		info.GetReturnValue().Set(info.This());
	}
	else
	{
		return;
	}
}

NAN_MODULE_INIT(Finder::Init)
{
	v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
	tpl->SetClassName(Nan::New("Finder").ToLocalChecked());
	tpl->InstanceTemplate()->SetInternalFieldCount(1);
	Nan::SetPrototypeMethod(tpl, "APIUnitsInches", APIUnitsInches);
	Nan::SetPrototypeMethod(tpl, "APIUnitsMM", APIUnitsMM);
	Nan::SetPrototypeMethod(tpl, "APIUnitsNative", APIUnitsNative);
	Nan::SetPrototypeMethod(tpl, "APIUnitsFeed", APIUnitsFeed);
	Nan::SetPrototypeMethod(tpl, "APIUnitsSpeed", APIUnitsSpeed);
	Nan::SetPrototypeMethod(tpl, "GetCompoundFeatureCount", GetCompoundFeatureCount);
	Nan::SetPrototypeMethod(tpl, "GetFaceEdgeCount", GetFaceEdgeCount);
	Nan::SetPrototypeMethod(tpl, "GetFaceEdgeNextPoint", GetFaceEdgeCount);
	Nan::SetPrototypeMethod(tpl, "GetFeatureID", GetFeatureID);
	Nan::SetPrototypeMethod(tpl, "GetFeatureName", GetFeatureName);
	Nan::SetPrototypeMethod(tpl, "GetMainWorkplan", GetMainWorkplan);
	Nan::SetPrototypeMethod(tpl, "GetProcessFeed", GetProcessFeed);
	Nan::SetPrototypeMethod(tpl, "GetProcessFeedUnit", GetProcessFeedUnit);
	Nan::SetPrototypeMethod(tpl, "OpenProject", OpenProject);
	Nan::SetPrototypeMethod(tpl, "SaveAsModules", SaveAsModules);
	Nan::SetPrototypeMethod(tpl, "SaveAsP21", SaveAsP21);
	constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked());
	Nan::Set(target, Nan::New("Finder").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked());
}

NAN_METHOD(Finder::APIUnitsFeed) {
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (!find) //Throw Exception
	return;
    if (info.Length() != 1) //Function takes one argument
	return;
    if (info[0]->IsUndefined()) //Argument should exist
	return;
    if (!info[0]->IsString()) //Throw Exception
	return;
    char * b;
    size_t len = v8StringToChar(info[0], b);
    if (!find->_find->api_unit_feed(b)) //Throw Exception
	return;
    delete[] b;
}
NAN_METHOD(Finder::APIUnitsInches) {

    Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (find == 0) {
	return; // Throw Exception
    }
    if (!(info[0]->IsUndefined())) { // function has 0 arguements
	return; //Throw Exeption
    }
    if (!find->_find->api_unit_inch()) {
	return; //throw error
    }
    return;

}

NAN_METHOD(Finder::APIUnitsMM) {

    Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());

    if (find == 0) {
	return; // Throw Exception
    }
    if (!(info[0]->IsUndefined())) { // function has 0 arguements
	return; //Throw Exeption
    }
    if (!find->_find->api_unit_mm()) {
	return; //throw error
    }
    return;
}

NAN_METHOD(Finder::APIUnitsNative) {

    Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());

    if (find == 0) {
	return; // Throw Exception
    }
    if (!(info[0]->IsUndefined())) { // function has 0 arguements
	return; //Throw Exeption
    }
    if (!find->_find->api_unit_native()) {
	return; //throw error
    }
    return;
}

NAN_METHOD(Finder::APIUnitsSpeed) {
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (!find) //Throw Exception
	return;
    if (info.Length() != 1) //Function takes one argument
	return;
    if (info[0]->IsUndefined()) //Argument should exist
	return;
    if (!info[0]->IsString()) //Throw Exception
	return;
    char * b;
    size_t len = v8StringToChar(info[0], b);
    if (!find->_find->api_unit_speed(b)) //Throw Exception
	return;
    delete[] b;
}

NAN_METHOD(Finder::GetCompoundFeatureCount) {

    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (find == 0) {
	return; //Throw an exception
    }
    if (info.Length() != 1) { // Needs one argument
	return; // Throw an exception
    }
    if (!info[0]->IsInt32()) { // argument of wrong type
	return; //Throw exception
    }
    int size = 0;
    int feature_id = 0;
    double x;
    double y;
    double z;

    if (!find->_find->first_feature_in_compound(info[0]->Int32Value(), feature_id, size, x, y, z)) {
	return; //throw Error
    }

    info.GetReturnValue().Set(size);
    return;
}

NAN_METHOD(Finder::GetExecutableDistance)
{
	Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) // Throw exception
		return;

	if (info.Length() != 1) // incorrect number of arguments
		return;

	if (!info[0]->IsNumber()) // invalid argument
		return;

	// get this executable's id
	int64_t exe_id = info[0]->IntegerValue();

	double distance = 0.0;
	double over_time, base_time;

	const char *str1, *str2;

	if (!find->_find->compute_best_feed_time(
		(int)exe_id, distance, base_time, over_time, str1, str2
		))	// cpp error
		return;

	info.GetReturnValue().Set(distance);
	return;
}

NAN_METHOD(Finder::GetFaceEdgeCount)
{
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (find == 0) //Throw Exception
	return;
    if (info[0]->IsUndefined()) //Needs one arg
	return;

    int count = 0;
    double dummy1, dummy2, dummy3;
    if (!find->_find->first_face_edge_point(info[0]->Int32Value(), count, dummy1, dummy2, dummy3))
	return;

    info.GetReturnValue().Set(count);
    return;
}

//{ret_x1:double, ret_y1:double, ret_z1:double, ret_x2:double, ret_y2:double, ret_z2:double}
NAN_METHOD(Finder::GetFaceEdgeNextPoint)
{
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (find == 0) //Throw Exception
	return;
    if (info.Length() < 8) //Needs 8 arg
	return;

    double x1 = 0.0;
    double y1 = 0.0;
    double z1 = 0.0;
    double x2 = 0.0;
    double y2 = 0.0;
    double z2 = 0.0;

    if (!find->_find->next_face_edge_point(Nan::To<int32_t>(info[0]).FromJust(),
	Nan::To<int32_t>(info[1]).FromJust(), x1, y1, z1, x2, y2, z2)) //Throw Exception
	return;

    v8::Local<v8::Object> jsonReturn = Nan::New<v8::Object>();
    jsonReturn->Set(CharTov8String("ret_x1"), info[2]);
    jsonReturn->Set(CharTov8String("ret_y1"), info[3]);
    jsonReturn->Set(CharTov8String("ret_z1"), info[4]);
    jsonReturn->Set(CharTov8String("ret_x2"), info[5]);
    jsonReturn->Set(CharTov8String("ret_y2"), info[6]);
    jsonReturn->Set(CharTov8String("ret_z2"), info[7]);

    info.GetReturnValue().Set(jsonReturn);
    return;
}

NAN_METHOD(Finder::GetFeatureID) {
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());

    if (info.Length() != 1)
	return;
    if (info[0]->IsUndefined())
	return;
    if (!info[0]->IsInt32())
	return;

    int feature_id = 0;

    if (!find->_find->feature_id(info[0]->Int32Value(), feature_id))
	return;

    info.GetReturnValue().Set(feature_id);
    return;
}

NAN_METHOD(Finder::GetFeatureName) {
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());

    if (info.Length() != 1)
	return;
    if (info[0]->IsUndefined())
	return;
    if (!info[0]->IsInt32())
	return;

    const char * name = 0;

    if (!find->_find->feature_name(info[0]->Int32Value(), name))
	return;

    info.GetReturnValue().Set(CharTov8String((char *)name));
    return;
}

NAN_METHOD(Finder::GetMainWorkplan) {
	Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) //Throw Exception
		return;
	if (!info[0]->IsUndefined()) //Function shouldn't get any arguments.
		return;
	int rtn = 0;
	int sz;
	if (!find->_find->main(rtn, sz))
		return;//Error in c++ code
	info.GetReturnValue().Set(rtn);
	return;
}

NAN_METHOD(Finder::GetProcessFeed) {
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (info.Length() != 1) //Throw Exception
	return;
    if (info[0]->IsUndefined()) //Throw Exception
	return;
    if (!info[0]->IsInt32()) //Throw Exception
	return;
    double feed = 0.0;
    double dummy;
    int ws_id = info[0]->Int32Value();
    if (!find->_find->feed_speed(ws_id, feed, dummy)) //Throw Exception
	return;
    info.GetReturnValue().Set(feed);
}

NAN_METHOD(Finder::GetProcessFeedUnit) {
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (info.Length() != 1) //Throw Exception
	return;
    if (info[0]->IsUndefined()) //Throw Exception
	return;
    if (!info[0]->IsInt32()) //Throw Exception
	return;
    const char* unit = "";
    const char* dummy = "";
    int ws_id = info[0]->Int32Value();
    if (!find->_find->feed_speed_unit(ws_id, (const char*&)unit, (const char*&)dummy)) //Throw Exception
	return;
    info.GetReturnValue().Set(CharTov8String((char *)unit));
}

NAN_METHOD(Finder::OpenProject) {
	Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) //Throw Exception
		return;
	if (info.Length() != 1) //Function should get one argument.
		return;
	if (!info[0]->IsString())
		return;
	char * fname = 0;
	ssize_t fnamelen = v8StringToChar(info[0], fname);
	if(!find->_find->search(fname)) //TODO: Handle Error.
		return;
	return; //Success finding, return.
}

NAN_METHOD(Finder::SaveAsModules)
{
    Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (find == 0) //Throw Exception
	return;

    if (!info[0]->IsUndefined())
	return;

    if (!info[0]->IsString())
	return;

    char* file_name_utf8;
    v8StringToChar(info[0], file_name_utf8);

    if (!find->_find->save_file(file_name_utf8, true)) //Throw Exception
	return;
}

NAN_METHOD(Finder::SaveAsP21)
{
	Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) //Throw Exception
		return;

	if (!info[0]->IsUndefined())
		return;

	if (!info[0]->IsString())
		return;

	char* file_name_utf8;
	v8StringToChar(info[0], file_name_utf8);

	if (!find->_find->save_file(file_name_utf8, false)) //Throw Exception
		return;
}<commit_msg>Added GetExecutableDistance to Init()<commit_after>// $RCSfile: $
// $Revision: $ $Date: $
// Auth: Samson Bonfante (bonfante@steptools.com)
//
// Copyright (c) 1991-2016 by STEP Tools Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "nodeFinder.h"
#include "nodeUtils.h"
Finder *Finder::_singleton = nullptr;

NAN_METHOD(Finder::New)
{
	if (info.IsConstructCall())
	{
		if (!info[0]->IsUndefined())
		{
			return;
		}
		if (_singleton == nullptr)
			_singleton = new Finder();
		_singleton->Wrap(info.This());
		info.GetReturnValue().Set(info.This());
	}
	else
	{
		return;
	}
}

NAN_MODULE_INIT(Finder::Init)
{
	v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
	tpl->SetClassName(Nan::New("Finder").ToLocalChecked());
	tpl->InstanceTemplate()->SetInternalFieldCount(1);
	Nan::SetPrototypeMethod(tpl, "APIUnitsInches", APIUnitsInches);
	Nan::SetPrototypeMethod(tpl, "APIUnitsMM", APIUnitsMM);
	Nan::SetPrototypeMethod(tpl, "APIUnitsNative", APIUnitsNative);
	Nan::SetPrototypeMethod(tpl, "APIUnitsFeed", APIUnitsFeed);
	Nan::SetPrototypeMethod(tpl, "APIUnitsSpeed", APIUnitsSpeed);
	Nan::SetPrototypeMethod(tpl, "GetCompoundFeatureCount", GetCompoundFeatureCount);
	Nan::SetPrototypeMethod(tpl, "GetExecutableDistance", GetExecutableDistance);
	Nan::SetPrototypeMethod(tpl, "GetFaceEdgeCount", GetFaceEdgeCount);
	Nan::SetPrototypeMethod(tpl, "GetFaceEdgeNextPoint", GetFaceEdgeCount);
	Nan::SetPrototypeMethod(tpl, "GetFeatureID", GetFeatureID);
	Nan::SetPrototypeMethod(tpl, "GetFeatureName", GetFeatureName);
	Nan::SetPrototypeMethod(tpl, "GetMainWorkplan", GetMainWorkplan);
	Nan::SetPrototypeMethod(tpl, "GetProcessFeed", GetProcessFeed);
	Nan::SetPrototypeMethod(tpl, "GetProcessFeedUnit", GetProcessFeedUnit);
	Nan::SetPrototypeMethod(tpl, "OpenProject", OpenProject);
	Nan::SetPrototypeMethod(tpl, "SaveAsModules", SaveAsModules);
	Nan::SetPrototypeMethod(tpl, "SaveAsP21", SaveAsP21);
	constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked());
	Nan::Set(target, Nan::New("Finder").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked());
}

NAN_METHOD(Finder::APIUnitsFeed) {
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (!find) //Throw Exception
	return;
    if (info.Length() != 1) //Function takes one argument
	return;
    if (info[0]->IsUndefined()) //Argument should exist
	return;
    if (!info[0]->IsString()) //Throw Exception
	return;
    char * b;
    size_t len = v8StringToChar(info[0], b);
    if (!find->_find->api_unit_feed(b)) //Throw Exception
	return;
    delete[] b;
}
NAN_METHOD(Finder::APIUnitsInches) {

    Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (find == 0) {
	return; // Throw Exception
    }
    if (!(info[0]->IsUndefined())) { // function has 0 arguements
	return; //Throw Exeption
    }
    if (!find->_find->api_unit_inch()) {
	return; //throw error
    }
    return;

}

NAN_METHOD(Finder::APIUnitsMM) {

    Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());

    if (find == 0) {
	return; // Throw Exception
    }
    if (!(info[0]->IsUndefined())) { // function has 0 arguements
	return; //Throw Exeption
    }
    if (!find->_find->api_unit_mm()) {
	return; //throw error
    }
    return;
}

NAN_METHOD(Finder::APIUnitsNative) {

    Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());

    if (find == 0) {
	return; // Throw Exception
    }
    if (!(info[0]->IsUndefined())) { // function has 0 arguements
	return; //Throw Exeption
    }
    if (!find->_find->api_unit_native()) {
	return; //throw error
    }
    return;
}

NAN_METHOD(Finder::APIUnitsSpeed) {
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (!find) //Throw Exception
	return;
    if (info.Length() != 1) //Function takes one argument
	return;
    if (info[0]->IsUndefined()) //Argument should exist
	return;
    if (!info[0]->IsString()) //Throw Exception
	return;
    char * b;
    size_t len = v8StringToChar(info[0], b);
    if (!find->_find->api_unit_speed(b)) //Throw Exception
	return;
    delete[] b;
}

NAN_METHOD(Finder::GetCompoundFeatureCount) {

    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (find == 0) {
	return; //Throw an exception
    }
    if (info.Length() != 1) { // Needs one argument
	return; // Throw an exception
    }
    if (!info[0]->IsInt32()) { // argument of wrong type
	return; //Throw exception
    }
    int size = 0;
    int feature_id = 0;
    double x;
    double y;
    double z;

    if (!find->_find->first_feature_in_compound(info[0]->Int32Value(), feature_id, size, x, y, z)) {
	return; //throw Error
    }

    info.GetReturnValue().Set(size);
    return;
}

NAN_METHOD(Finder::GetExecutableDistance)
{
	Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) // Throw exception
		return;

	if (info.Length() != 1) // incorrect number of arguments
		return;

	if (!info[0]->IsNumber()) // invalid argument
		return;

	// get this executable's id
	int64_t exe_id = info[0]->IntegerValue();

	double distance = 0.0;
	double over_time, base_time;

	const char *str1, *str2;

	if (!find->_find->compute_best_feed_time(
		(int)exe_id, distance, base_time, over_time, str1, str2
		))	// cpp error
		return;

	info.GetReturnValue().Set(distance);
	return;
}

NAN_METHOD(Finder::GetFaceEdgeCount)
{
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (find == 0) //Throw Exception
	return;
    if (info[0]->IsUndefined()) //Needs one arg
	return;

    int count = 0;
    double dummy1, dummy2, dummy3;
    if (!find->_find->first_face_edge_point(info[0]->Int32Value(), count, dummy1, dummy2, dummy3))
	return;

    info.GetReturnValue().Set(count);
    return;
}

//{ret_x1:double, ret_y1:double, ret_z1:double, ret_x2:double, ret_y2:double, ret_z2:double}
NAN_METHOD(Finder::GetFaceEdgeNextPoint)
{
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (find == 0) //Throw Exception
	return;
    if (info.Length() < 8) //Needs 8 arg
	return;

    double x1 = 0.0;
    double y1 = 0.0;
    double z1 = 0.0;
    double x2 = 0.0;
    double y2 = 0.0;
    double z2 = 0.0;

    if (!find->_find->next_face_edge_point(Nan::To<int32_t>(info[0]).FromJust(),
	Nan::To<int32_t>(info[1]).FromJust(), x1, y1, z1, x2, y2, z2)) //Throw Exception
	return;

    v8::Local<v8::Object> jsonReturn = Nan::New<v8::Object>();
    jsonReturn->Set(CharTov8String("ret_x1"), info[2]);
    jsonReturn->Set(CharTov8String("ret_y1"), info[3]);
    jsonReturn->Set(CharTov8String("ret_z1"), info[4]);
    jsonReturn->Set(CharTov8String("ret_x2"), info[5]);
    jsonReturn->Set(CharTov8String("ret_y2"), info[6]);
    jsonReturn->Set(CharTov8String("ret_z2"), info[7]);

    info.GetReturnValue().Set(jsonReturn);
    return;
}

NAN_METHOD(Finder::GetFeatureID) {
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());

    if (info.Length() != 1)
	return;
    if (info[0]->IsUndefined())
	return;
    if (!info[0]->IsInt32())
	return;

    int feature_id = 0;

    if (!find->_find->feature_id(info[0]->Int32Value(), feature_id))
	return;

    info.GetReturnValue().Set(feature_id);
    return;
}

NAN_METHOD(Finder::GetFeatureName) {
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());

    if (info.Length() != 1)
	return;
    if (info[0]->IsUndefined())
	return;
    if (!info[0]->IsInt32())
	return;

    const char * name = 0;

    if (!find->_find->feature_name(info[0]->Int32Value(), name))
	return;

    info.GetReturnValue().Set(CharTov8String((char *)name));
    return;
}

NAN_METHOD(Finder::GetMainWorkplan) {
	Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) //Throw Exception
		return;
	if (!info[0]->IsUndefined()) //Function shouldn't get any arguments.
		return;
	int rtn = 0;
	int sz;
	if (!find->_find->main(rtn, sz))
		return;//Error in c++ code
	info.GetReturnValue().Set(rtn);
	return;
}

NAN_METHOD(Finder::GetProcessFeed) {
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (info.Length() != 1) //Throw Exception
	return;
    if (info[0]->IsUndefined()) //Throw Exception
	return;
    if (!info[0]->IsInt32()) //Throw Exception
	return;
    double feed = 0.0;
    double dummy;
    int ws_id = info[0]->Int32Value();
    if (!find->_find->feed_speed(ws_id, feed, dummy)) //Throw Exception
	return;
    info.GetReturnValue().Set(feed);
}

NAN_METHOD(Finder::GetProcessFeedUnit) {
    Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (info.Length() != 1) //Throw Exception
	return;
    if (info[0]->IsUndefined()) //Throw Exception
	return;
    if (!info[0]->IsInt32()) //Throw Exception
	return;
    const char* unit = "";
    const char* dummy = "";
    int ws_id = info[0]->Int32Value();
    if (!find->_find->feed_speed_unit(ws_id, (const char*&)unit, (const char*&)dummy)) //Throw Exception
	return;
    info.GetReturnValue().Set(CharTov8String((char *)unit));
}

NAN_METHOD(Finder::OpenProject) {
	Finder* find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) //Throw Exception
		return;
	if (info.Length() != 1) //Function should get one argument.
		return;
	if (!info[0]->IsString())
		return;
	char * fname = 0;
	ssize_t fnamelen = v8StringToChar(info[0], fname);
	if(!find->_find->search(fname)) //TODO: Handle Error.
		return;
	return; //Success finding, return.
}

NAN_METHOD(Finder::SaveAsModules)
{
    Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
    if (find == 0) //Throw Exception
	return;

    if (!info[0]->IsUndefined())
	return;

    if (!info[0]->IsString())
	return;

    char* file_name_utf8;
    v8StringToChar(info[0], file_name_utf8);

    if (!find->_find->save_file(file_name_utf8, true)) //Throw Exception
	return;
}

NAN_METHOD(Finder::SaveAsP21)
{
	Finder * find = Nan::ObjectWrap::Unwrap<Finder>(info.This());
	if (find == 0) //Throw Exception
		return;

	if (!info[0]->IsUndefined())
		return;

	if (!info[0]->IsString())
		return;

	char* file_name_utf8;
	v8StringToChar(info[0], file_name_utf8);

	if (!find->_find->save_file(file_name_utf8, false)) //Throw Exception
		return;
}<|endoftext|>


<commit_before>#include <object/global.hh>
#include <object/slot.hh>
#include <object/symbols.hh>

namespace object
{
  rObject
  Slot::property_get(libport::Symbol k)
  {
    if (k == SYMBOL(changed))
    {
      if (!changed_)
      {
        CAPTURE_GLOBAL(Event);
        changed_ = Event->call(SYMBOL(new));
      }
      return changed_;
    }
    properties_type::iterator it = properties_.find(k);
    if (it == properties_.end())
      return 0;
    else
      return it->second;
  }

  bool
  Slot::property_has(libport::Symbol k)
  {
    return properties_.find(k) != properties_.end();
  }

  bool
  Slot::property_set(libport::Symbol k, rObject value)
  {
    bool res = !property_has(k);
    properties_[k] = value;
    return res;
  }

  void
  Slot::property_remove(libport::Symbol k)
  {
    properties_.erase(k);
  }

  Slot::properties_type&
  Slot::properties_get()
  {
    return properties_;
  }
}

<commit_msg>Add forgotten include.<commit_after>#include <object/global.hh>
#include <object/slot.hh>
#include <object/slot.hxx>
#include <object/symbols.hh>

namespace object
{
  rObject
  Slot::property_get(libport::Symbol k)
  {
    if (k == SYMBOL(changed))
    {
      if (!changed_)
      {
        CAPTURE_GLOBAL(Event);
        changed_ = Event->call(SYMBOL(new));
      }
      return changed_;
    }
    properties_type::iterator it = properties_.find(k);
    if (it == properties_.end())
      return 0;
    else
      return it->second;
  }

  bool
  Slot::property_has(libport::Symbol k)
  {
    return properties_.find(k) != properties_.end();
  }

  bool
  Slot::property_set(libport::Symbol k, rObject value)
  {
    bool res = !property_has(k);
    properties_[k] = value;
    return res;
  }

  void
  Slot::property_remove(libport::Symbol k)
  {
    properties_.erase(k);
  }

  Slot::properties_type&
  Slot::properties_get()
  {
    return properties_;
  }
}

<|endoftext|>


<commit_before>#ifdef COMPONENT_PARSER_H
#ifndef COMPONENT_PARSER_OPERATION_H
#define COMPONENT_PARSER_OPERATION_H

namespace Operations {
	const Token nullval("null", KEYWORD, CONSTANT);

	Token add(Token, Token);
	Token subtract(Token, Token);
	Token multiply(Token, Token);
	Token divide(Token, Token);
	Token modulo(Token, Token);
	Token mathOperator(String, Token, Token);

	Token compare(String, Token, Token);
	Token logical(String, Token, Token);

	int priority(String);
	int comparePriority(String, String);

    bool isInteger(Token);
	double toNumber(Token);
	String toString(Token);
	long toInteger(Token);

};

Token Operations::mathOperator(String op, Token a, Token b) {/*
	if (op == "+") return add(a, b);
	if (op == "-") return subtract(a, b);
	if (op == "*") return multiply(a, b);
	if (op == "/") return divide(a, b);
	if (op == "%") return modulo(a, b);
	*/
	return nullval;
}

int Operations::priority(String op) {
	if (op == ".") return 6;
	if (op == "++" || op == "--") return 5;
	if (op == "*" || op == "/" || op == "%")  return 4;
    if (op == "+" || op == "-") return 3;
    if (op.substr(0,2) == "==" || op.substr(0, 2) == "!=" || op[0] == '<' || op[0] == '>') return 2;
    if (op == "!" || op == "&&" || op == "||" || op == "=" || op[1] == '=') return 1;
    return 0;
}

int Operations::comparePriority(String a, String b) {
	return priority(a) - priority(b);
}

bool Operations::isInteger(Token t) {
    if(t.value().indexOf(".") == -1) return true;
    return false;
}

double Operations::toNumber(Token t) {
    if(t.subtype() != NUMBER) return 0.0;
    double val = 0.0,beginning = 0;
    if(t.value()[0] == '-') beginning = 1;
    if(isInteger(t)){
        for(int i = t.value().length()-1, j = 1;i >= beginning;i--, j *= 10) {
            val += double((t.value()[i] - '0') * j);
        }
        if(beginning == 1) val *= -1.0;
        return val;
    }
    else{
        long long pos=t.value().indexOf(".");
        for(int i = pos-1, j = 1;i >= beginning;i--, j *= 10) {
            val += double((t.value()[i] - '0') * j);
        }
        double j = 0.1;
        for(int i = pos+1;i < t.value().length();i++, j /= 10.0){
            val += double(t.value()[i]-'0') * j;
        }
        if(beginning == 1) val *= -1.0;
        return val;
    }
}

long Operations::toInteger(Token t) {
    if(!isInteger(t)) return 0;
    return int(toNumber(t));
}

String Operations::toString(Token t) {
    if(t.subtype() != STRING) return "";
    return t.value().substr(1, t.value().length() - 2);
}

#endif /* COMPONENT_PARSER_OPERATION_H */
#endif /* COMPONENT_PARSER_H */
<commit_msg>remove deprecated functions<commit_after>#ifdef COMPONENT_PARSER_H
#ifndef COMPONENT_PARSER_OPERATION_H
#define COMPONENT_PARSER_OPERATION_H

namespace Operations {
	const Token nullval("null", KEYWORD, CONSTANT);

	Token add(Token, Token);
	Token subtract(Token, Token);
	Token multiply(Token, Token);
	Token divide(Token, Token);
	Token modulo(Token, Token);
	Token mathOperator(String, Token, Token);

	Token compare(String, Token, Token);
	Token logical(String, Token, Token);

	int priority(String);
	int comparePriority(Token, Token);

};

Token Operations::mathOperator(String op, Token a, Token b) {/*
	if (op == "+") return add(a, b);
	if (op == "-") return subtract(a, b);
	if (op == "*") return multiply(a, b);
	if (op == "/") return divide(a, b);
	if (op == "%") return modulo(a, b);
	*/
	return nullval;
}

int Operations::priority(String op) {
	if (op == ".") return 6;
	if (op == "++" || op == "--") return 5;
	if (op == "*" || op == "/" || op == "%")  return 4;
	if (op == "+" || op == "-") return 3;
	if (op.substr(0,2) == "==" || op.substr(0, 2) == "!=" || op[0] == '<' || op[0] == '>') return 2;
	if (op == "!" || op == "&&" || op == "||" || op == "=" || op[1] == '=') return 1;
	return 0;
}

int Operations::comparePriority(Token a, Token b) {
	return priority(a.value()) - priority(b.value());
}

#endif /* COMPONENT_PARSER_OPERATION_H */
#endif /* COMPONENT_PARSER_H */
<|endoftext|>


<commit_before>/**
   Parse gaps in a given BAM alignment and output the resulting gaps in BED or
   VCF formats.
 */
#include <string>
#include <tclap/CmdLine.h>

int main(int argc, char** argv) {
    try {
        TCLAP::CmdLine cmd("Parse gaps in BAM alignments", ' ', "0.1");
        TCLAP::UnlabeledValueArg<std::string> arg_reference("reference", "path to a FASTA file for the reference used by the given BAM", true, "", "reference");
        TCLAP::UnlabeledValueArg<std::string> arg_bam("bam", "path to a BAM file to parse", true, "", "bam");

        cmd.add(arg_reference);
        cmd.add(arg_bam);
        cmd.parse(argc, argv);
    }
    catch (TCLAP::ArgException &e) {
        std::cerr << "Error: " << e.error() << " for arg " << e.argId() << std::endl;
    }

    return 0;
}
<commit_msg>open reference FASTA and BAM prior to parsing. closes #2.<commit_after>/**
   Parse gaps in a given BAM alignment and output the resulting gaps in BED or
   VCF formats.
 */
#include <string>
#include <tclap/CmdLine.h>
#include <seqan/sequence.h>
#include <seqan/seq_io.h>
#include <seqan/bam_io.h>

using namespace seqan;

int main(int argc, char** argv) {
    try {
        TCLAP::CmdLine cmd("Parse gaps in BAM alignments", ' ', "0.1");
        TCLAP::UnlabeledValueArg<std::string> arg_reference("reference", "path to a FASTA file for the reference used by the given BAM", true, "", "reference");
        TCLAP::UnlabeledValueArg<std::string> arg_bam("bam", "path to a BAM file to parse", true, "", "bam");

        cmd.add(arg_reference);
        cmd.add(arg_bam);
        cmd.parse(argc, argv);

        /**
           Open the FASTA file for the given reference.
         */
        std::string reference_file_name = arg_reference.getValue();
        FaiIndex fai_index;
        if (!open(fai_index, toCString(reference_file_name))) {
            std::cerr << "Error: Could not open FASTA index for reference: " << reference_file_name << std::endl;
            return 1;
        }

        /**
           Open the BAM file of alignments to the given reference.
         */
        std::string bam_file_name = arg_bam.getValue();
        BamFileIn bam_file_in;
        if (!open(bam_file_in, toCString(bam_file_name))) {
            std::cerr << "Error: Could not open BAM: " << bam_file_name << std::endl;
            return 1;
        }
    }
    catch (TCLAP::ArgException &e) {
        std::cerr << "Error: " << e.error() << " for arg " << e.argId() << std::endl;
    }

    return 0;
}
<|endoftext|>


<commit_before>
#include "geo2emp.h"

#include <iostream>

#include <Ni.h>
#include <NgBody.h>
#include <NgEmp.h>
#include <NgString.h>

/**
 * Process a mesh-type naiad body
 */
int loadMeshShape(GU_Detail& gdp, Ng::ShapeCPtr pShape);
int loadParticleShape(GU_Detail& gdp, const Ng::Body* pBody);
int loadFieldShape(GU_Detail& gdp, Ng::ShapeCPtr pShape);

/*************************************************************************************************/

/**
 * Load all the Naiad bodies from the EMP file into the Houdini GDP
 *
 */
int loadEmpBodies(std::string filen, GU_Detail& gdp)
{
	Ng::EmpReader* empReader = NULL;

	NiBegin(NI_BODY_ONLY);

	//std::cout << "loading emp bodies from: " << filen << std::endl;

	unsigned int numBodies = 0;
	try
	{
		//std::cout << "Create new emp reader." << std::endl;
		Ng::String ngfilen = Ng::String(filen);
		empReader = new Ng::EmpReader( ngfilen );
		//std::cout << "getting body count..." << std::endl;
		//std::cout << "body count: " << empReader->bodyCount() << std::endl;
		numBodies = empReader->bodyCount();
		//std::cout << "Found " << numBodies << " bodies in emp file " << std::endl;

	}
	catch( std::exception& e )
	{
		//TODO: generate a proper error / exit code for Houdini.
		// return exit code?
		//std::cout << "exception! " << e.what() << std::endl;
		return 1;
	}

	//Run through each body and process them according to their shape type.
	const Ng::Body* pBody = 0;
	Ng::Body::ConstShapeMapIter shapeIt;
	for (int i = 0; i < numBodies; i++)
	{
		pBody = empReader->constBody(i);
		//std::cout << i << ":" << pBody->name() << std::endl;
		//std::cout << "number of shapes: " << pBody->shape_count() << std::endl;

		//Iterate over the shapes for this body.
		for (shapeIt = pBody->beginShapes(); shapeIt != pBody->endShapes(); shapeIt++)
		{
			//std::cout << "Shape type: " << shapeIt->first << std::endl;
			if (shapeIt->first == "Particle")
			{
				loadParticleShape(gdp, pBody);
			}
			else if (shapeIt->first == "Field")
			{
				loadFieldShape(gdp, shapeIt->second);
			}
			else if (shapeIt->first == "Mesh")
			{
				loadMeshShape(gdp, shapeIt->second);
			}
			else
			{
				//std::cout << "Found unsupported shape type: " << shapeIt->first << std::endl;
			}
		}

	}

	NiEnd();

	//Return success
	return 0;
}

/*************************************************************************************************/

int loadMeshShape(GU_Detail& gdp, Ng::ShapeCPtr pShape)
{
	//std::cout << "============= Loading mesh shape ===============" << std::endl;

	return 0;
}

/*************************************************************************************************/

/**
 * Process a Naiad channel and add the attribute to the point
 */
void processPointChannel(GU_Detail& gdp, GEO_Point* ppt, const Ng::ChannelCPtr& chan)
{
	/**
	 * If the channel does not exist, then create it
	 */

	if (chan->name() == "position")
	{
		//Set the point position
		//const Ng::ParticleChannel3f &chanPos = chan->constChannel3f( ppt->getNum() );
		//ppt->setPos( chanPos[0], chanPos[1], chanPos[2] );
	}

}

int loadParticleShape(GU_Detail& gdp, const Ng::Body* pBody)
{
	const Ng::ParticleShape* pShape;
	//std::cout << "============= Loading particle shape ===============" << std::endl;

	pShape = pBody->queryConstParticleShape();

	if (!pShape)
	{
		//std::cout << "Received NULL particle shape!" << std::endl;
		return 1;
	}

	//We have a valid particle shape. Start copying particle data over to the GDP
	int64_t size = pShape->size();
	int channelCount = pShape->channelCount();
	GEO_Point *ppt;
	std::vector<std::string> houdiniNames; //houdini names that correspond to naiad channels.

	//std::cout << "Size: " << size << std::endl;
	//std::cout << "Channel count: " << channelCount << std::endl;

	//Iterate over the channels and create the corresponding attributes in the GDP
	for (int i = 0; i < channelCount; i++)
	{
		const Ng::ChannelCPtr& chan = pShape->channel(i);

		if ( chan->name() == "position" )
			houdiniNames.push_back("P");
		else if (chan->name() == "velocity" )
			houdiniNames.push_back("v");
		else
			houdiniNames.push_back( chan->name() );

		//std::cout << "channel: " << chan->name() << " size: " << chan->size() << std::endl;
	}

	//The channel values for particle shapes are stored in blocks/tiles.
	const Ng::TileLayout& layout = pBody->constLayout();
	unsigned int numBlocks = layout.tileCount();

	//Get the block array for the positions channel
	const em::block3_array3f& positionBlocks( pShape->constBlocks3f("position") );

	for (int blockIndex = 0; blockIndex < numBlocks; blockIndex ++)
	{
		//Get a single block from the position blocks
		const em::block3vec3f& posBlock = positionBlocks(blockIndex);

		//std::cout << "pos block index: " << blockIndex << " size: " << posBlock.size() << std::endl;
		//Iterate over all the points in the position block
		for (int i = 0; i < posBlock.size(); i++)
		{
			ppt = gdp.appendPoint();
			//std::cout << "pos: " << i << " " << posBlock(i)[0] << posBlock(i)[1] << std::endl;
			ppt->setPos( UT_Vector3( posBlock(i)[0], posBlock(i)[1], posBlock(i)[2] ) );
		}

	}

	return 0;
}

/*************************************************************************************************/

int loadFieldShape(GU_Detail& gdp, Ng::ShapeCPtr pShape)
{
	//std::cout << "============= Loading field shape ===============" << std::endl;

	return 0;
}

/*************************************************************************************************/

<commit_msg>Particles and their velocities can now be imported into Houdini. There is existing code to import any attributes present on the particles but is not complete yet.<commit_after>
#include "geo2emp.h"

#include <iostream>

#include <GEO/GEO_AttributeHandle.h>

#include <Ni.h>
#include <NgBody.h>
#include <NgEmp.h>
#include <NgString.h>

/**
 * Process a mesh-type naiad body
 */
int loadMeshShape(GU_Detail& gdp, Ng::ShapeCPtr pShape);
int loadParticleShape(GU_Detail& gdp, const Ng::Body* pBody);
int loadFieldShape(GU_Detail& gdp, Ng::ShapeCPtr pShape);

/*************************************************************************************************/

/**
 * Load all the Naiad bodies from the EMP file into the Houdini GDP
 *
 */
int loadEmpBodies(std::string filen, GU_Detail& gdp)
{
	Ng::EmpReader* empReader = NULL;

	NiBegin(NI_BODY_ONLY);

	//std::cout << "loading emp bodies from: " << filen << std::endl;

	unsigned int numBodies = 0;
	try
	{
		//std::cout << "Create new emp reader." << std::endl;
		Ng::String ngfilen = Ng::String(filen);
		empReader = new Ng::EmpReader( ngfilen );
		//std::cout << "getting body count..." << std::endl;
		//std::cout << "body count: " << empReader->bodyCount() << std::endl;
		numBodies = empReader->bodyCount();
		//std::cout << "Found " << numBodies << " bodies in emp file " << std::endl;

	}
	catch( std::exception& e )
	{
		//TODO: generate a proper error / exit code for Houdini.
		// return exit code?
		//std::cout << "exception! " << e.what() << std::endl;
		return 1;
	}

	//Run through each body and process them according to their shape type.
	const Ng::Body* pBody = 0;
	Ng::Body::ConstShapeMapIter shapeIt;
	for (int i = 0; i < numBodies; i++)
	{
		pBody = empReader->constBody(i);
		//std::cout << i << ":" << pBody->name() << std::endl;
		//std::cout << "number of shapes: " << pBody->shape_count() << std::endl;

		//Iterate over the shapes for this body.
		for (shapeIt = pBody->beginShapes(); shapeIt != pBody->endShapes(); shapeIt++)
		{
			//std::cout << "Shape type: " << shapeIt->first << std::endl;
			if (shapeIt->first == "Particle")
			{
				loadParticleShape(gdp, pBody);
			}
			else if (shapeIt->first == "Field")
			{
				loadFieldShape(gdp, shapeIt->second);
			}
			else if (shapeIt->first == "Mesh")
			{
				loadMeshShape(gdp, shapeIt->second);
			}
			else
			{
				//std::cout << "Found unsupported shape type: " << shapeIt->first << std::endl;
			}
		}

	}

	NiEnd();

	//Return success
	return 0;
}

/*************************************************************************************************/

int loadMeshShape(GU_Detail& gdp, Ng::ShapeCPtr pShape)
{
	//std::cout << "============= Loading mesh shape ===============" << std::endl;

	return 0;
}

/*************************************************************************************************/

/**
 * Process a Naiad channel and add the attribute to the point
 */
void processPointChannel(GU_Detail& gdp, GEO_Point* ppt, const Ng::ChannelCPtr& chan)
{
	/**
	 * If the channel does not exist, then create it
	 */

	if (chan->name() == "position")
	{
		//Set the point position
		//const Ng::ParticleChannel3f &chanPos = chan->constChannel3f( ppt->getNum() );
		//ppt->setPos( chanPos[0], chanPos[1], chanPos[2] );
	}

}

int loadParticleShape(GU_Detail& gdp, const Ng::Body* pBody)
{
	const Ng::ParticleShape* pShape;
	//std::cout << "============= Loading particle shape ===============" << std::endl;

	pShape = pBody->queryConstParticleShape();

	if (!pShape)
	{
		//std::cout << "Received NULL particle shape!" << std::endl;
		return 1;
	}

	//We have a valid particle shape. Start copying particle data over to the GDP
	int64_t size = pShape->size();
	int channelCount = pShape->channelCount();
	int positionChannelIndex = 0;
	GEO_Point *ppt;
	GEO_AttributeHandle attr;
	std::vector<std::string> houdiniNames; //houdini names that correspond to naiad channels.
	//Default values for attributes
	float zero3f[3] = {0,0,0};
	float zero1f = 0;
	int zero3i[3] = {0,0,0};
	int zero1i = 0;

	//std::cout << "Size: " << size << std::endl;
	//std::cout << "Channel count: " << channelCount << std::endl;

	//Iterate over the channels and create the corresponding attributes in the GDP
	for (int i = 0; i < channelCount; i++)
	{
		const Ng::ChannelCPtr& chan = pShape->channel(i);

		if ( chan->name() == "position" )
		{
			houdiniNames.push_back("P");
			positionChannelIndex = i;
			//std::cout << "Setting position channel index: " << i << std::endl;
			//GDPs always have a P attribute, so no need to create on explicitly.
		}
		else if (chan->name() == "velocity" )
		{
			houdiniNames.push_back("v");
			attr = gdp.getPointAttribute("v");
			if ( !attr.isAttributeValid() )
			{
				gdp.addPointAttrib( "v", sizeof(float)*3, GB_ATTRIB_VECTOR, zero3f );
				attr = gdp.getPointAttribute( "v" );
			}
		}
		else
		{
			houdiniNames.push_back( chan->name() );
			attr = gdp.getPointAttribute( chan->name().c_str() );
			if ( !attr.isAttributeValid() )
			{
				//If the attribute doesn't exist yet, then create a new one based on the Naiad type.
				//(Hopefully we don't have name clashes!!)

				int size;
				GB_AttribType type;
				void* data;

				switch ( chan->type() )
				{
					case Ng::ValueBase::FloatType:
						//Create a single float attribute.
						size = sizeof(float);
						type = GB_ATTRIB_FLOAT;
						data = &zero1f;
						break;
					case Ng::ValueBase::IntType:
						//Create a single float attribute.
						size = sizeof(int);
						type = GB_ATTRIB_INT;
						data = &zero1i;
						break;
					case Ng::ValueBase::Vec3fType:
						//Create a tuple of 3 floats.
						size = sizeof(float)*3;
						type = GB_ATTRIB_FLOAT;
						data = zero3f;
						break;
					case Ng::ValueBase::Vec3iType:
						//Create a tuple of 3 ints.
						size = sizeof(int)*3;
						type = GB_ATTRIB_FLOAT;
						data = zero3i;
						break;

					default:
						//Unsupported type...now what??
						break;

				}

				gdp.addPointAttrib( chan->name().c_str(), size, type, data );
				attr = gdp.getPointAttribute( chan->name().c_str() );
			}

		}

		//std::cout << "channel: " << chan->name() << " size: " << chan->size() << std::endl;
	}

	//The channel values for particle shapes are stored in blocks/tiles.
	const Ng::TileLayout& layout = pBody->constLayout();
	unsigned int numBlocks = layout.tileCount();

	//Get the block array for the positions channel
	const em::block3_array3f& positionBlocks( pShape->constBlocks3f("position") );

	for (int blockIndex = 0; blockIndex < numBlocks; blockIndex ++)
	{
		//Get a single block from the position blocks
		const em::block3vec3f& posBlock = positionBlocks(blockIndex);

		//std::cout << "taking block from positions..." << blockIndex << std::endl;
		//std::cout << "block size:" << posBlock.size() << std::endl;
		//Iterate over all the points/particles in the position block
		for (int ptNum = 0; ptNum < posBlock.size(); ptNum++)
		{
			ppt = gdp.appendPoint();
			//std::cout << "pos: " << i << " " << posBlock(i)[0] << posBlock(i)[1] << std::endl;
			ppt->setPos( UT_Vector3( posBlock(ptNum)[0], posBlock(ptNum)[1], posBlock(ptNum)[2] ) );

			//Loop over the channels and add the attributes
			for (int channelIndex = 0; channelIndex < channelCount; channelIndex++)
			{
				//std::cout << "processing channel index: " << channelIndex << std::endl;
				if (channelIndex == positionChannelIndex)
					//Skip special case channels. Currently, the only special case channel is positions.
					continue;

				//TODO: normals and velocities should be added as VECTORS, not FLOATS

				const Ng::ChannelCPtr& chan = pShape->channel(channelIndex);
				//std::cout << "inspecting channel: " << channelIndex << ":" << chan->name() << std::endl;
				//Fill the attributes data in the Houdini GDP. (The attributes have been created in the first channel loop).
				switch ( chan->type() )
				{
					case Ng::ValueBase::FloatType:
					{
						//std::cout << "got float attrib: " << chan->name() << std::endl;
						//Get the created channel data
						const em::block3f& channelData( pShape->constBlocks1f(chan->name())(blockIndex) );
						//Get the Houdini point attribute using the name list we built earlier.
						attr = gdp.getPointAttribute( houdiniNames[channelIndex].c_str() );
						attr.setElement(ppt);

					}
					break;
					case Ng::ValueBase::IntType:
					{
						//std::cout << "got int attrib: " << chan->name() << std::endl;
						//Get the created channel data
						const em::block3f& channelData( pShape->constBlocks1f(chan->name())(blockIndex) );
						//Get the Houdini point attribute using the name list we built earlier.
						attr = gdp.getPointAttribute( houdiniNames[channelIndex].c_str() );
						attr.setElement(ppt);

					}
					break;
					case Ng::ValueBase::Vec3fType:
					{
						//std::cout << "got float3 attrib: " << chan->name() << std::endl;
						//Get the created channel data
						const em::block3vec3f& channelData( pShape->constBlocks3f(channelIndex)(blockIndex) );
						//Get the Houdini point attribute using the name list we built earlier.
						attr = gdp.getPointAttribute( houdiniNames[channelIndex].c_str() );
						attr.setElement(ppt);
						attr.setV3( UT_Vector3( channelData(ptNum)[0], channelData(ptNum)[1], channelData(ptNum)[2]  ) );

					}
					break;
					case Ng::ValueBase::Vec3iType:
					{
						//std::cout << "got int3 attrib: " << chan->name() << std::endl;
						//Get the created channel data
						const em::block3vec3i& channelData( pShape->constBlocks3i(chan->name())(blockIndex) );
						//Get the Houdini point attribute using the name list we built earlier.
						attr = gdp.getPointAttribute( houdiniNames[channelIndex].c_str() );
						attr.setElement(ppt);

					}
					break;

					default:
						//std::cout << "got non-float attrib." << chan->name() << std::endl;
						break;

				}

			}

		}

	}

	//std::cout << "all done. " << std::endl;
	return 0;
}

/*************************************************************************************************/

int loadFieldShape(GU_Detail& gdp, Ng::ShapeCPtr pShape)
{
	//std::cout << "============= Loading field shape ===============" << std::endl;

	return 0;
}

/*************************************************************************************************/

<|endoftext|>


<commit_before>#include "py-gil-lock.h"
#include <uv.h>

namespace GILLock {
void Init() {
    static PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();

    static uv_prepare_t gilrelease;
    static uv_check_t gilensure;

    uv_prepare_init(uv_default_loop(), &gilrelease);
    uv_check_init(uv_default_loop(), &gilensure);
    uv_prepare_start(&gilrelease, [] (uv_prepare_t *) {
        PyGILState_Release(gstate);
    });
    uv_check_start(&gilensure, [] (uv_check_t *) {
        gstate = PyGILState_Ensure();
    });
}
} // namespace GILLock
<commit_msg>seems work<commit_after>#include "py-gil-lock.h"
#include <uv.h>
#include <iostream>

namespace GILLock {
void Init() {
    static PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();

    static uv_prepare_t gilrelease;
    static uv_check_t gilensure;

    uv_prepare_init(uv_default_loop(), &gilrelease);
    uv_check_init(uv_default_loop(), &gilensure);
    uv_prepare_start(&gilrelease, [] (uv_prepare_t *) {
        PyGILState_Release(gstate);
    });
    uv_check_start(&gilensure, [] (uv_check_t *) {
        if (uv_loop_alive(uv_default_loop())) {
            std::cout << "alive" << std::endl;
            gstate = PyGILState_Ensure();
        }
    });
    uv_unref((uv_handle_t *)&gilrelease);
    uv_unref((uv_handle_t *)&gilensure);
}
} // namespace GILLock
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2004  Justin Karneges
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include "qca_plugin.h"

#include <QtCore>
#include "qcaprovider.h"

#define PLUGIN_SUBDIR "crypto"

namespace QCA {

class ProviderItem
{
public:
	Provider *p;
	QString fname;
	int priority;

	static ProviderItem *load(const QString &fname)
	{
		QPluginLoader *lib = new QPluginLoader(fname);
		QCAPlugin *plugin = qobject_cast<QCAPlugin*>(lib->instance());
		if(!plugin || plugin->version() != QCA_PLUGIN_VERSION)
		{
			delete lib;
			return 0;
		}

		Provider *p = plugin->createProvider();
		if(!p)
		{
			delete lib;
			return 0;
		}

		ProviderItem *i = new ProviderItem(lib, p);
		i->fname = fname;
		return i;
	}

	static ProviderItem *loadStatic(QObject *instance)
	{
		QCAPlugin *plugin = qobject_cast<QCAPlugin*>(instance);
		if(!plugin || plugin->version() != QCA_PLUGIN_VERSION)
			return 0;

		Provider *p = plugin->createProvider();
		if(!p)
			return 0;

		ProviderItem *i = new ProviderItem(0, p);
		return i;
	}

	static ProviderItem *fromClass(Provider *p)
	{
		ProviderItem *i = new ProviderItem(0, p);
		return i;
	}

	~ProviderItem()
	{
		delete p;
		delete lib;
	}

	void ensureInit()
	{
		if(init_done)
			return;
		init_done = true;
		p->init();
	}

private:
	QPluginLoader *lib;
	bool init_done;

	ProviderItem(QPluginLoader *_lib, Provider *_p)
	{
		lib = _lib;
		p = _p;
		init_done = false;
	}
};

ProviderManager::ProviderManager()
{
	def = 0;
	scanned_static = false;
}

ProviderManager::~ProviderManager()
{
	delete def;
}

void ProviderManager::scan()
{
	// check static first, but only once
	if(!scanned_static)
	{
		QObjectList list = QPluginLoader::staticInstances();
		for(int n = 0; n < list.count(); ++n)
		{
			QObject *instance = list[n];
			ProviderItem *i = ProviderItem::loadStatic(instance);
			if(!i)
				continue;

			if(i->p && haveAlready(i->p->name()))
			{
				delete i;
				continue;
			}

			addItem(i, -1);
		}
		scanned_static = true;
	}

	// check plugin files
	QStringList dirs = QCoreApplication::libraryPaths();
	for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it)
	{
		QDir libpath(*it);
		QDir dir(libpath.filePath(PLUGIN_SUBDIR));
		if(!dir.exists())
			continue;

		QStringList list = dir.entryList();
		for(QStringList::ConstIterator it = list.begin(); it != list.end(); ++it)
		{
			QFileInfo fi(dir.filePath(*it));
			if(fi.isDir())
				continue;
			QString fname = fi.filePath();

			ProviderItem *i = ProviderItem::load(fname);
			if(!i)
				continue;

			if(i->p && haveAlready(i->p->name()))
			{
				delete i;
				continue;
			}

			addItem(i, -1);
		}
	}
}

bool ProviderManager::add(Provider *p, int priority)
{
	if(haveAlready(p->name()))
		return false;

	ProviderItem *i = ProviderItem::fromClass(p);
	addItem(i, priority);
	return true;
}

void ProviderManager::unload(const QString &name)
{
	for(int n = 0; n < providerItemList.count(); ++n)
	{
		ProviderItem *i = providerItemList[n];
		if(i->p && i->p->name() == name)
		{
			delete i;
			providerItemList.removeAt(n);
			providerList.removeAt(n);
			return;
		}
	}
}

void ProviderManager::unloadAll()
{
	qDeleteAll(providerItemList);
	providerItemList.clear();
	providerList.clear();
}

void ProviderManager::setDefault(Provider *p)
{
	if(def)
		delete def;
	def = p;
	if(def)
		def->init();
}

Provider *ProviderManager::find(Provider *p) const
{
	if(p == def)
		return def;

	for(int n = 0; n < providerItemList.count(); ++n)
	{
		ProviderItem *i = providerItemList[n];
		if(i->p && i->p == p)
		{
			i->ensureInit();
			return i->p;
		}
	}
	return 0;
}

Provider *ProviderManager::find(const QString &name) const
{
	if(def && name == def->name())
		return def;

	for(int n = 0; n < providerItemList.count(); ++n)
	{
		ProviderItem *i = providerItemList[n];
		if(i->p && i->p->name() == name)
		{
			i->ensureInit();
			return i->p;
		}
	}
	return 0;
}

Provider *ProviderManager::findFor(const QString &name, const QString &type) const
{
	if(name.isEmpty())
	{
		// find the first one that can do it
		for(int n = 0; n < providerItemList.count(); ++n)
		{
			ProviderItem *i = providerItemList[n];
			i->ensureInit();
			if(i->p && i->p->features().contains(type))
				return i->p;
		}

		// try the default provider as a last resort
		if(def && def->features().contains(type))
			return def;

		return 0;
	}
	else
	{
		Provider *p = find(name);
		if(p && p->features().contains(type))
			return p;
		return 0;
	}
}

void ProviderManager::changePriority(const QString &name, int priority)
{
	ProviderItem *i = 0;
	int n = 0;
	for(; n < providerItemList.count(); ++n)
	{
		ProviderItem *pi = providerItemList[n];
		if(pi->p && pi->p->name() == name)
		{
			i = pi;
			break;
		}
	}
	if(!i)
		return;

	providerItemList.removeAt(n);
	providerList.removeAt(n);

	addItem(i, priority);
}

int ProviderManager::getPriority(const QString &name)
{
	ProviderItem *i = 0;
	for(int n = 0; n < providerItemList.count(); ++n)
	{
		ProviderItem *pi = providerItemList[n];
		if(pi->p && pi->p->name() == name)
		{
			i = pi;
			break;
		}
	}
	if(!i)
		return -1;

	return i->priority;
}

QStringList ProviderManager::allFeatures() const
{
	QStringList list;

	if(def)
		list = def->features();

	for(int n = 0; n < providerItemList.count(); ++n)
	{
		ProviderItem *i = providerItemList[n];
		if(i->p)
			mergeFeatures(&list, i->p->features());
	}

	return list;
}

const ProviderList & ProviderManager::providers() const
{
	return providerList;
}

void ProviderManager::addItem(ProviderItem *item, int priority)
{
	if(priority < 0)
	{
		// for -1, make the priority the same as the last item
		if(!providerItemList.isEmpty())
		{
			ProviderItem *last = providerItemList.last();
			item->priority = last->priority;
		}
		else
			item->priority = 0;

		providerItemList.append(item);
		providerList.append(item->p);
	}
	else
	{
		// place the item before any other items with same or greater priority
		int n = 0;
		for(; n < providerItemList.count(); ++n)
		{
			ProviderItem *i = providerItemList[n];
			if(i->priority >= priority)
				break;
		}

		item->priority = priority;
		providerItemList.insert(n, item);
		providerList.insert(n, item->p);
	}
}

bool ProviderManager::haveAlready(const QString &name) const
{
	return ((def && name == def->name()) || find(name));
}

void ProviderManager::mergeFeatures(QStringList *a, const QStringList &b)
{
	for(QStringList::ConstIterator it = b.begin(); it != b.end(); ++it)
	{
		if(!a->contains(*it))
			a->append(*it);
	}
}

}
<commit_msg>don't load plugins more than once.  also, do moveToThread(0) on them<commit_after>/*
 * Copyright (C) 2004  Justin Karneges
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include "qca_plugin.h"

#include <QtCore>
#include "qcaprovider.h"

#define PLUGIN_SUBDIR "crypto"

namespace QCA {

class ProviderItem
{
public:
	QString fname;
	Provider *p;
	int priority;

	static ProviderItem *load(const QString &fname)
	{
		//printf("trying to load [%s]\n", qPrintable(fname));
		QPluginLoader *lib = new QPluginLoader(fname);
		QCAPlugin *plugin = qobject_cast<QCAPlugin*>(lib->instance());
		if(!plugin || plugin->version() != QCA_PLUGIN_VERSION)
		{
			delete plugin;
			delete lib;
			return 0;
		}
		//printf("success\n");

		Provider *p = plugin->createProvider();
		if(!p)
		{
			delete plugin;
			delete lib;
			return 0;
		}

		ProviderItem *i = new ProviderItem(lib, plugin, p);
		i->fname = fname;
		return i;
	}

	static ProviderItem *loadStatic(QObject *instance)
	{
		QCAPlugin *plugin = qobject_cast<QCAPlugin*>(instance);
		if(!plugin || plugin->version() != QCA_PLUGIN_VERSION)
		{
			delete plugin;
			return 0;
		}

		Provider *p = plugin->createProvider();
		if(!p)
		{
			delete plugin;
			return 0;
		}

		ProviderItem *i = new ProviderItem(0, plugin, p);
		return i;
	}

	static ProviderItem *fromClass(Provider *p)
	{
		ProviderItem *i = new ProviderItem(0, 0, p);
		return i;
	}

	~ProviderItem()
	{
		delete p;
		delete qcaPlugin;
		delete lib;
	}

	void ensureInit()
	{
		if(init_done)
			return;
		init_done = true;
		p->init();
	}

private:
	QPluginLoader *lib;
	QCAPlugin *qcaPlugin;
	bool init_done;

	ProviderItem(QPluginLoader *_lib, QCAPlugin *_qcaPlugin, Provider *_p)
	{
		lib = _lib;
		qcaPlugin = _qcaPlugin;
		p = _p;
		init_done = false;

		// disassociate from threads
		if(qcaPlugin)
			qcaPlugin->moveToThread(0);
		if(lib)
			lib->moveToThread(0);
	}
};

ProviderManager::ProviderManager()
{
	def = 0;
	scanned_static = false;
}

ProviderManager::~ProviderManager()
{
	delete def;
}

void ProviderManager::scan()
{
	// check static first, but only once
	if(!scanned_static)
	{
		QObjectList list = QPluginLoader::staticInstances();
		for(int n = 0; n < list.count(); ++n)
		{
			QObject *instance = list[n];
			ProviderItem *i = ProviderItem::loadStatic(instance);
			if(!i)
				continue;

			if(i->p && haveAlready(i->p->name()))
			{
				delete i;
				continue;
			}

			addItem(i, -1);
		}
		scanned_static = true;
	}

	// check plugin files
	QStringList dirs = QCoreApplication::libraryPaths();
	for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it)
	{
		QDir libpath(*it);
		QDir dir(libpath.filePath(PLUGIN_SUBDIR));
		if(!dir.exists())
			continue;

		QStringList list = dir.entryList();
		for(QStringList::ConstIterator it = list.begin(); it != list.end(); ++it)
		{
			QFileInfo fi(dir.filePath(*it));
			if(fi.isDir())
				continue;
			QString fname = fi.filePath();

			// make sure we haven't loaded this file before
			bool haveFile = false;
			for(int n = 0; n < providerItemList.count(); ++n)
			{
				ProviderItem *pi = providerItemList[n];
				if(!pi->fname.isEmpty() && pi->fname == fname)
				{
					haveFile = true;
					break;
				}
			}
			if(haveFile)
				continue;

			ProviderItem *i = ProviderItem::load(fname);
			if(!i)
				continue;

			if(i->p && haveAlready(i->p->name()))
			{
				delete i;
				continue;
			}

			addItem(i, -1);
		}
	}
}

bool ProviderManager::add(Provider *p, int priority)
{
	if(haveAlready(p->name()))
		return false;

	ProviderItem *i = ProviderItem::fromClass(p);
	addItem(i, priority);
	return true;
}

void ProviderManager::unload(const QString &name)
{
	for(int n = 0; n < providerItemList.count(); ++n)
	{
		ProviderItem *i = providerItemList[n];
		if(i->p && i->p->name() == name)
		{
			delete i;
			providerItemList.removeAt(n);
			providerList.removeAt(n);
			return;
		}
	}
}

void ProviderManager::unloadAll()
{
	qDeleteAll(providerItemList);
	providerItemList.clear();
	providerList.clear();
}

void ProviderManager::setDefault(Provider *p)
{
	if(def)
		delete def;
	def = p;
	if(def)
		def->init();
}

Provider *ProviderManager::find(Provider *p) const
{
	if(p == def)
		return def;

	for(int n = 0; n < providerItemList.count(); ++n)
	{
		ProviderItem *i = providerItemList[n];
		if(i->p && i->p == p)
		{
			i->ensureInit();
			return i->p;
		}
	}
	return 0;
}

Provider *ProviderManager::find(const QString &name) const
{
	if(def && name == def->name())
		return def;

	for(int n = 0; n < providerItemList.count(); ++n)
	{
		ProviderItem *i = providerItemList[n];
		if(i->p && i->p->name() == name)
		{
			i->ensureInit();
			return i->p;
		}
	}
	return 0;
}

Provider *ProviderManager::findFor(const QString &name, const QString &type) const
{
	if(name.isEmpty())
	{
		// find the first one that can do it
		for(int n = 0; n < providerItemList.count(); ++n)
		{
			ProviderItem *i = providerItemList[n];
			i->ensureInit();
			if(i->p && i->p->features().contains(type))
				return i->p;
		}

		// try the default provider as a last resort
		if(def && def->features().contains(type))
			return def;

		return 0;
	}
	else
	{
		Provider *p = find(name);
		if(p && p->features().contains(type))
			return p;
		return 0;
	}
}

void ProviderManager::changePriority(const QString &name, int priority)
{
	ProviderItem *i = 0;
	int n = 0;
	for(; n < providerItemList.count(); ++n)
	{
		ProviderItem *pi = providerItemList[n];
		if(pi->p && pi->p->name() == name)
		{
			i = pi;
			break;
		}
	}
	if(!i)
		return;

	providerItemList.removeAt(n);
	providerList.removeAt(n);

	addItem(i, priority);
}

int ProviderManager::getPriority(const QString &name)
{
	ProviderItem *i = 0;
	for(int n = 0; n < providerItemList.count(); ++n)
	{
		ProviderItem *pi = providerItemList[n];
		if(pi->p && pi->p->name() == name)
		{
			i = pi;
			break;
		}
	}
	if(!i)
		return -1;

	return i->priority;
}

QStringList ProviderManager::allFeatures() const
{
	QStringList list;

	if(def)
		list = def->features();

	for(int n = 0; n < providerItemList.count(); ++n)
	{
		ProviderItem *i = providerItemList[n];
		if(i->p)
			mergeFeatures(&list, i->p->features());
	}

	return list;
}

const ProviderList & ProviderManager::providers() const
{
	return providerList;
}

void ProviderManager::addItem(ProviderItem *item, int priority)
{
	if(priority < 0)
	{
		// for -1, make the priority the same as the last item
		if(!providerItemList.isEmpty())
		{
			ProviderItem *last = providerItemList.last();
			item->priority = last->priority;
		}
		else
			item->priority = 0;

		providerItemList.append(item);
		providerList.append(item->p);
	}
	else
	{
		// place the item before any other items with same or greater priority
		int n = 0;
		for(; n < providerItemList.count(); ++n)
		{
			ProviderItem *i = providerItemList[n];
			if(i->priority >= priority)
				break;
		}

		item->priority = priority;
		providerItemList.insert(n, item);
		providerList.insert(n, item->p);
	}
}

bool ProviderManager::haveAlready(const QString &name) const
{
	return ((def && name == def->name()) || find(name));
}

void ProviderManager::mergeFeatures(QStringList *a, const QStringList &b)
{
	for(QStringList::ConstIterator it = b.begin(); it != b.end(); ++it)
	{
		if(!a->contains(*it))
			a->append(*it);
	}
}

}
<|endoftext|>