<commit_before>#include <sys/mount.h>
#include <v8.h>
#include <node.h>
#include <errno.h>
#include <string.h>
#include <iostream>

//Uses an example of kkaefer's node addon tutorials for an async worker
//
//Link for the used template:
//https://github.com/kkaefer/node-cpp-modules/blob/master/05_threadpool/modulename.cpp#L88

using namespace v8;

Handle<Value> Mount(const Arguments &args);
void AsyncMount(uv_work_t* req);
void AsyncUmount(uv_work_t *req);
void AsyncAfter(uv_work_t* req);

struct Mounty {
    Persistent<Function> callback;

    //All values excpect target are only used by mount
    std::string devFile;
    std::string fsType;
    std::string target; //used by umount
    std::string data;
    int flags;

    int error;
};

//        0         1       2       3       4
//mount(devFile, target, fsType, options, data)
Handle<Value> Mount(const Arguments &args) {
    HandleScope scope;

    int argsLength = args.Length();
    if (argsLength <= 2) {
        return ThrowException(Exception::Error(String::New("mount needs at least 3 parameters")));
    }

    Local<Function> cb;
    Handle<Array> options = Array::New(0);
    Local<Value> data = String::New("");

    if(!args[0]->IsString() || !args[1]->IsString() || !args[2]->IsString()){
        return ThrowException(Exception::Error(String::New("Invalid arguments")));
    }

    //Check and set options array (ignores all non-array values)
    if(argsLength >= 3) {
        if (args[3]->IsArray()) {
            options = Handle<Array>::Cast(args[3]);
        }
    }

    if(argsLength == 6) {
        if (args[4]->IsString()) {
            data = args[4];
        }
    }

    //Set callback, if provided as last argument
    if(args[argsLength - 1]->IsFunction()){
        cb = Local<Function>::Cast(args[argsLength - 1]);
    }
    else{
        cb = FunctionTemplate::New()->GetFunction();
    }

    int flags = 0;
    for (unsigned int i = 0; i < options->Length(); i++) {
        String::Utf8Value str(options->Get(i)->ToString());

        if(!strcmp(*str, "bind")) {
            flags |= MS_BIND;
        } else if(!strcmp(*str, "readonly")) {
            flags |= MS_RDONLY;
        } else if(!strcmp(*str, "remount")) {
            flags |= MS_REMOUNT;
        } else if(!strcmp(*str, "noexec")){
            flags |= MS_NOEXEC;
        } else{
            //return ThrowException(Exception::Error(String::New(strcat("Invalid option: ", *str))));
            return ThrowException(Exception::Error(String::New("Invalid option")));
        }
    }

    String::Utf8Value devFile(args[0]->ToString());
    String::Utf8Value target(args[1]->ToString());
    String::Utf8Value fsType(args[2]->ToString());
    String::Utf8Value dataStr(data->ToString());

    //Prepare data for the async work
    Mounty* mounty = new Mounty();

    mounty->callback = Persistent<Function>::New(cb);

    mounty->devFile = std::string(*devFile);
    mounty->target = std::string(*target);
    mounty->fsType = std::string(*fsType);
    mounty->data = std::string(*dataStr);
    mounty->flags = flags;

    //Create the Async work and set the prepared data
    uv_work_t *req = new uv_work_t();
    req->data = mounty;

    int status = uv_queue_work(uv_default_loop(), req, AsyncMount, (uv_after_work_cb)AsyncAfter);

    assert(status == 0);

    return scope.Close(Undefined());
}

void AsyncMount(uv_work_t* req){
    Mounty* mounty = static_cast<Mounty*>(req->data);

    int ret = mount(mounty->devFile.c_str(),
                    mounty->target.c_str(),
                    mounty->fsType.c_str(),
                    mounty->flags,
                    mounty->data.c_str());

    //Save error-code
    if(ret == -1){
        mounty->error = errno;
    }
}

//Used for both, mount and umount since they have the same callback interface
void AsyncAfter(uv_work_t* req){
    HandleScope scope;
    Mounty* mounty = static_cast<Mounty*>(req->data);

    const unsigned argc = 1;
    Local<Value> argv[argc];

    //Call error-callback, if error... otherwise send result
    if(mounty->error > 0){
        char *errStr = strerror(mounty->error);
        Local<String> s = String::New(errStr);
        Local<Object> err = Exception::Error(s)->ToObject();
        err->Set(String::NewSymbol("code"), String::New(strerror(mounty->error)));
        err->Set(String::NewSymbol("errno"), Integer::New((int32_t)mounty->error));

        //const unsigned argc = 1;
        argv[0] = err;

        //TryCatch tc;
        //mounty->callback->Call(Context::GetCurrent()->Global(), argc, argv);

        //if(tc.HasCaught()){
            //node::FatalException(tc);
        //}
    } else {
        //const unsigned argc = 1;
        argv[0] = Local<Value>::New(Null());

        //TryCatch tc;
        //mounty->callback->Call(Context::GetCurrent()->Global(), argc, argv);

        //if(tc.HasCaught()){
            //node::FatalException(tc);
        //}
    }

    TryCatch tc;
    mounty->callback->Call(Context::GetCurrent()->Global(), argc, argv);

    if(tc.HasCaught()){
        node::FatalException(tc);
    }

    mounty->callback.Dispose();

    delete mounty;
    delete req;
}

Handle<Value> Umount(const Arguments &args) {
    HandleScope scope;

    if (args.Length() < 1) {
        return ThrowException(String::New("Missing argument 'target'"));
    }

    Local<Function> cb;

    if(args.Length() == 2 && args[1]->IsFunction()) {
        cb = Local<Function>::Cast(args[1]);
    }
    else{
        cb = FunctionTemplate::New()->GetFunction();
    }

    String::Utf8Value target(args[0]->ToString());

    //Prepare data for the async work
    Mounty* mounty = new Mounty();

    mounty->callback = Persistent<Function>::New(cb);
    mounty->target = std::string(*target);

    //Create the Async work and set the prepared data
    uv_work_t *req = new uv_work_t();
    req->data = mounty;

    int status = uv_queue_work(uv_default_loop(), req, AsyncUmount, (uv_after_work_cb)AsyncAfter);

    assert(status == 0);

    return scope.Close(Undefined());
}

void AsyncUmount(uv_work_t *req){
    Mounty* mounty = static_cast<Mounty*>(req->data);

    int ret = umount(mounty->target.c_str());

    //Save error-code
    if(ret == -1){
        mounty->error = errno;
    }
}

void init (Handle<Object> exports, Handle<Object> module) {
    exports->Set(String::NewSymbol("mount"), FunctionTemplate::New(Mount)->GetFunction());
    exports->Set(String::NewSymbol("umount"), FunctionTemplate::New(Umount)->GetFunction());
}

NODE_MODULE(mount, init)
<commit_msg>Better error reporting using nodes ErrnoException<commit_after>#include <sys/mount.h>
#include <v8.h>
#include <node.h>
#include <errno.h>
#include <string.h>
#include <iostream>

//Uses an example of kkaefer's node addon tutorials for an async worker
//
//Link for the used template:
//https://github.com/kkaefer/node-cpp-modules/blob/master/05_threadpool/modulename.cpp#L88

using namespace v8;

Handle<Value> Mount(const Arguments &args);
void AsyncMount(uv_work_t* req);
void AsyncUmount(uv_work_t *req);
void AsyncAfter(uv_work_t* req);

struct Mounty {
    Persistent<Function> callback;

    //All values excpect target are only used by mount
    std::string devFile;
    std::string fsType;
    std::string target; //used by umount
    std::string data;
    int flags;

    int error;
};

//        0         1       2       3       4
//mount(devFile, target, fsType, options, data)
Handle<Value> Mount(const Arguments &args) {
    HandleScope scope;

    int argsLength = args.Length();
    if (argsLength <= 2) {
        return ThrowException(Exception::Error(String::New("mount needs at least 3 parameters")));
    }

    Local<Function> cb;
    Handle<Array> options = Array::New(0);
    Local<Value> data = String::New("");

    if(!args[0]->IsString() || !args[1]->IsString() || !args[2]->IsString()){
        return ThrowException(Exception::Error(String::New("Invalid arguments")));
    }

    //Check and set options array (ignores all non-array values)
    if(argsLength >= 3) {
        if (args[3]->IsArray()) {
            options = Handle<Array>::Cast(args[3]);
        }
    }

    if(argsLength == 6) {
        if (args[4]->IsString()) {
            data = args[4];
        }
    }

    //Set callback, if provided as last argument
    if(args[argsLength - 1]->IsFunction()){
        cb = Local<Function>::Cast(args[argsLength - 1]);
    }
    else{
        cb = FunctionTemplate::New()->GetFunction();
    }

    int flags = 0;
    for (unsigned int i = 0; i < options->Length(); i++) {
        String::Utf8Value str(options->Get(i)->ToString());

        if(!strcmp(*str, "bind")) {
            flags |= MS_BIND;
        } else if(!strcmp(*str, "readonly")) {
            flags |= MS_RDONLY;
        } else if(!strcmp(*str, "remount")) {
            flags |= MS_REMOUNT;
        } else if(!strcmp(*str, "noexec")){
            flags |= MS_NOEXEC;
        } else{
            //return ThrowException(Exception::Error(String::New(strcat("Invalid option: ", *str))));
            return ThrowException(Exception::Error(String::New("Invalid option")));
        }
    }

    String::Utf8Value devFile(args[0]->ToString());
    String::Utf8Value target(args[1]->ToString());
    String::Utf8Value fsType(args[2]->ToString());
    String::Utf8Value dataStr(data->ToString());

    //Prepare data for the async work
    Mounty* mounty = new Mounty();

    mounty->callback = Persistent<Function>::New(cb);

    mounty->devFile = std::string(*devFile);
    mounty->target = std::string(*target);
    mounty->fsType = std::string(*fsType);
    mounty->data = std::string(*dataStr);
    mounty->flags = flags;

    //Create the Async work and set the prepared data
    uv_work_t *req = new uv_work_t();
    req->data = mounty;

    int status = uv_queue_work(uv_default_loop(), req, AsyncMount, (uv_after_work_cb)AsyncAfter);

    assert(status == 0);

    return scope.Close(Undefined());
}

void AsyncMount(uv_work_t* req){
    Mounty* mounty = static_cast<Mounty*>(req->data);

    int ret = mount(mounty->devFile.c_str(),
                    mounty->target.c_str(),
                    mounty->fsType.c_str(),
                    mounty->flags,
                    mounty->data.c_str());

    //Save error-code
    if(ret == -1){
        mounty->error = errno;
    }
}

//Used for both, mount and umount since they have the same callback interface
void AsyncAfter(uv_work_t* req){
    HandleScope scope;
    Mounty* mounty = static_cast<Mounty*>(req->data);

    const unsigned argc = 1;
    Local<Value> argv[argc];

    //Call error-callback, if error... otherwise send result
    if(mounty->error > 0){
        Local<Value> err = node::ErrnoException(mounty->error);
        //char *errStr = strerror(mounty->error);
        //Local<String> s = String::New(errStr);
        //Local<Object> err = Exception::Error(s)->ToObject();
        //err->Set(String::NewSymbol("code"), String::New(strerror(mounty->error)));
        //err->Set(String::NewSymbol("errno"), Integer::New((int32_t)mounty->error));

        //const unsigned argc = 1;
        argv[0] = err;

        //TryCatch tc;
        //mounty->callback->Call(Context::GetCurrent()->Global(), argc, argv);

        //if(tc.HasCaught()){
            //node::FatalException(tc);
        //}
    } else {
        //const unsigned argc = 1;
        argv[0] = Local<Value>::New(Null());

        //TryCatch tc;
        //mounty->callback->Call(Context::GetCurrent()->Global(), argc, argv);

        //if(tc.HasCaught()){
            //node::FatalException(tc);
        //}
    }

    TryCatch tc;
    mounty->callback->Call(Context::GetCurrent()->Global(), argc, argv);

    if(tc.HasCaught()){
        node::FatalException(tc);
    }

    mounty->callback.Dispose();

    delete mounty;
    delete req;
}

Handle<Value> Umount(const Arguments &args) {
    HandleScope scope;

    if (args.Length() < 1) {
        return ThrowException(String::New("Missing argument 'target'"));
    }

    Local<Function> cb;

    if(args.Length() == 2 && args[1]->IsFunction()) {
        cb = Local<Function>::Cast(args[1]);
    }
    else{
        cb = FunctionTemplate::New()->GetFunction();
    }

    String::Utf8Value target(args[0]->ToString());

    //Prepare data for the async work
    Mounty* mounty = new Mounty();

    mounty->callback = Persistent<Function>::New(cb);
    mounty->target = std::string(*target);

    //Create the Async work and set the prepared data
    uv_work_t *req = new uv_work_t();
    req->data = mounty;

    int status = uv_queue_work(uv_default_loop(), req, AsyncUmount, (uv_after_work_cb)AsyncAfter);

    assert(status == 0);

    return scope.Close(Undefined());
}

void AsyncUmount(uv_work_t *req){
    Mounty* mounty = static_cast<Mounty*>(req->data);

    int ret = umount(mounty->target.c_str());

    //Save error-code
    if(ret == -1){
        mounty->error = errno;
    }
}

void init (Handle<Object> exports, Handle<Object> module) {
    exports->Set(String::NewSymbol("mount"), FunctionTemplate::New(Mount)->GetFunction());
    exports->Set(String::NewSymbol("umount"), FunctionTemplate::New(Umount)->GetFunction());
}

NODE_MODULE(mount, init)
<|endoftext|>


<commit_before>/***************************************************************************
* Copyright (C) 2007 Eddie Carle [eddie@erctech.org]                       *
*                                                                          *
* This file is part of fastcgi++.                                          *
*                                                                          *
* fastcgi++ 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 3 of the License, or (at *
* your option) any later version.                                          *
*                                                                          *
* fastcgi++ 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 fastcgi++.  If not, see <http://www.gnu.org/licenses/>.       *
****************************************************************************/

#include <fstream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/asio.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <fastcgi++/request.hpp>
#include <fastcgi++/manager.hpp>
#include <string>
#include <net/sf1r/Sf1DriverBase.hpp>
#include <net/sf1r/Sf1Driver.hpp>
#include <net/sf1r/distributed/Sf1DistributedDriver.hpp>
#include <3rdparty/rapidjson/document.h>
#include <3rdparty/rapidjson/stringbuffer.h>
#include <3rdparty/rapidjson/writer.h>

using namespace std;
using namespace izenelib::net::sf1r;
using namespace boost::posix_time;
using boost::asio::ip::udp;

namespace rj = rapidjson;
// I like to have an independent error log file to keep track of exceptions while debugging.
// You might want a different filename. I just picked this because everything has access there.
void error_log(const std::string& msg)
{
	using namespace std;
	using namespace boost;
	static ofstream error;
	if(!error.is_open())
	{
		error.open("/tmp/sf1r_errlog", ios_base::out | ios_base::app);
		error.imbue(locale(error.getloc(), new posix_time::time_facet()));
	}

	error << "PID: " << (long)getpid() << " [" << posix_time::microsec_clock::local_time() << "] " << msg << endl;
}

// Let's make our request handling class. It must do the following:
// 1) Be derived from Fastcgipp::Request
// 2) Define the virtual response() member function from Fastcgipp::Request()

// First things first let's decide on what kind of character set we will use.
// Since we want to be able to echo all languages we will use unicode. The way this
// library handles unicode might be different than some are used to but it is done
// the way it is supposed to be. All internal characters are wide. In this case UTF-32.
// This way we don't have to mess around with variable size characters in our program.
// A string with 10 wchar_ts is ten characters long. Not up in the air as it is with UTF-8.
// Anyway, moving right along, the streams will code convert all the UTF-32 data to UTF-8
// before it is sent out to the client. This way we get the best of both worlds.
//
// So, whenever we are going to use UTF-8, our template parameter for Fastcgipp::Request<charT>
// should be wchar_t. Keep in mind that this suddendly makes
// everything wide character and utf compatible. Including HTTP header data (cookies, urls, yada-yada).

class Sf1rProcess: public Fastcgipp::Request<char>
{
	bool response()
	{
		using namespace Fastcgipp;

        if(environment().requestMethod != Http::HTTP_METHOD_GET &&
            environment().requestMethod != Http::HTTP_METHOD_POST )
        {
            out << "Status: 403 Forbidden\r\n\r\n";
            return true;
        }

        std::string requri = environment().requestUri;
        //error_log("got sf1r request: " + requri);
        if (requri.find("/sf1r") == 0)
            requri.replace(0, 5, "");
        std::string tokens = environment().findCustomHeader("HTTP_X_IZENESOFT_ACL_TOKENS");
        if (!tokens.empty())
        {
            error_log("using tokens : " + tokens);
        }
        std::string body = environment().raw_post.raw_post_data;
        if(!body.empty() && environment().raw_post.type == Http::Post<char>::raw)
        {
            //error_log("post raw data: " + body);
        }
		else
        {
            out << "Status: 400 Bad Request\r\n\r\n";
            return true;
        }

        std::string response;
        assert(driver);
        try
        {
            std::string log_content;
            rj::Document document;
            rj::Document::AllocatorType& allocator = document.GetAllocator();
            document.SetObject();
            rj::Value& top = document;
            rj::Value tag(log_tag.c_str(), log_tag.length(), allocator);
            top.AddMember("tag", tag, allocator);
            rj::Value request_body(body.c_str(), body.length(), allocator);
            top.AddMember("request", request_body, allocator);
            rj::Value request_uri(requri.c_str(), requri.length(), allocator);
            top.AddMember("uri", request_uri, allocator);
            std::string time_str = to_simple_string(microsec_clock::local_time());
            rj::Value msec(time_str.c_str(), time_str.length(), allocator);
            top.AddMember("msec", msec, allocator);

            rj::StringBuffer stream;
            rj::Writer<rj::StringBuffer> writer(stream);
            document.Accept(writer);
            log_content.assign(stream.GetString(), stream.GetSize());
            boost::system::error_code ec;
            s.send_to(boost::asio::buffer(log_content.data(), log_content.size()),
                destination, 0, ec);

            if(ec)
            {
                error_log("send log to fluentd failed.");
            }

            response = driver->call(requri, tokens, body);
        }
        catch (ClientError& e) {
            error_log(std::string("ClientError: ") + e.what());
            out << "Status: 400 Bad Request\r\n\r\n";
            return true;
        } catch (ServerError& e) {
            error_log(std::string("ServerError: ") + e.what());
            out << "Status: 502 Bad GateWay\r\n\r\n";
            return true;
        } catch (RoutingError& e) {
            error_log(std::string("RoutingError: ") + e.what());
            out << "Status: 503 Service Unavailable\r\n\r\n";
            return true;
        } catch (NetworkError& e) {
            error_log(std::string("NetworkError: ") + e.what());
            out << "Status: 504 GateWay Time out\r\n\r\n";
            return true;
        } catch (std::exception& e) {
            error_log(std::string("Exception: ") + e.what());
            out << "Status: 500 Internal Server Error\r\n\r\n";
            return true;
        }

        out << "Content-Type: application/json\r\nContent-Length: " << response.size() << "\r\n\r\n";
        out.dump((const char*)response.data(), response.size());

		return true;
	}
public:
    static Sf1DriverBase* driver;
    static boost::asio::io_service io_service;
    static boost::asio::ip::udp::endpoint destination;
    static udp::socket s;
    static std::string log_tag;
};

Sf1DriverBase* Sf1rProcess::driver = NULL;
boost::asio::io_service Sf1rProcess::io_service;
udp::socket Sf1rProcess::s(Sf1rProcess::io_service);
boost::asio::ip::udp::endpoint Sf1rProcess::destination;
std::string Sf1rProcess::log_tag;

int main(int argc, char* argv[])
{
	try
	{
        if (argc < 5)
        {
            error_log("arg not enough. sf1rhost:sf1rport fluent_ip fluent_port fluent_tag ");
            return -1;
        }
        std::string host( "180.153.140.110:2181,180.153.140.111:2181,180.153.140.112:2181" );
        host = argv[1];
        std::string fluent_ip = argv[2];
        std::string fluent_port = argv[3];
        Sf1rProcess::log_tag = argv[4];
        std::string distributed;
        if(argc > 5)
        {
            distributed = argv[5];
        }
        std::string match_master;
        if (argc > 6)
        {
            match_master = argv[6];
        }
        error_log("args:" + host + "," + fluent_ip + "," + fluent_port + "," + Sf1rProcess::log_tag +
            "," + distributed + "," + match_master);
        if(distributed.empty())
        {
            Sf1Config conf;
            conf.initialSize = 2;
            conf.resize = 2;
            conf.maxSize = 4;
            conf.timeout = 30;
            Sf1rProcess::driver = new Sf1Driver(host, conf);
        }
        else
        {
            Sf1DistributedConfig dconf;
            dconf.initialSize = 2;
            dconf.resize = 2;
            dconf.maxSize = 4;
            dconf.timeout = 30;
            dconf.zkTimeout = 2000;  //ms
            dconf.match_master_name = match_master;
            Sf1rProcess::driver = new Sf1DistributedDriver(host, dconf);
            error_log("config as distributed sf1r node");
        }

        Sf1rProcess::destination.address(boost::asio::ip::address::from_string(fluent_ip));
        Sf1rProcess::destination.port(boost::lexical_cast<unsigned short>(fluent_port));
        Sf1rProcess::s.open(udp::v4());
		// First we make a Fastcgipp::Manager object, with our request handling class
		// as a template parameter.
		Fastcgipp::Manager<Sf1rProcess> fcgi;
		// Now just call the object handler function. It will sleep quietly when there
		// are no requests and efficiently manage them when there are many.
		fcgi.handler();
	}
	catch(std::exception& e)
	{
        error_log("sf1r cgi process init failed, exited.");
        error_log(e.what());
	}
    if (Sf1rProcess::driver)
        delete Sf1rProcess::driver;
    return -1;
}
<commit_msg>use msec in log<commit_after>/***************************************************************************
* Copyright (C) 2007 Eddie Carle [eddie@erctech.org]                       *
*                                                                          *
* This file is part of fastcgi++.                                          *
*                                                                          *
* fastcgi++ 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 3 of the License, or (at *
* your option) any later version.                                          *
*                                                                          *
* fastcgi++ 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 fastcgi++.  If not, see <http://www.gnu.org/licenses/>.       *
****************************************************************************/

#include <fstream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/asio.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <fastcgi++/request.hpp>
#include <fastcgi++/manager.hpp>
#include <string>
#include <net/sf1r/Sf1DriverBase.hpp>
#include <net/sf1r/Sf1Driver.hpp>
#include <net/sf1r/distributed/Sf1DistributedDriver.hpp>
#include <3rdparty/rapidjson/document.h>
#include <3rdparty/rapidjson/stringbuffer.h>
#include <3rdparty/rapidjson/writer.h>

using namespace std;
using namespace izenelib::net::sf1r;
using namespace boost::posix_time;
using boost::asio::ip::udp;

namespace rj = rapidjson;
// I like to have an independent error log file to keep track of exceptions while debugging.
// You might want a different filename. I just picked this because everything has access there.
void error_log(const std::string& msg)
{
	using namespace std;
	using namespace boost;
	static ofstream error;
	if(!error.is_open())
	{
		error.open("/tmp/sf1r_errlog", ios_base::out | ios_base::app);
		error.imbue(locale(error.getloc(), new posix_time::time_facet()));
	}

	error << "PID: " << (long)getpid() << " [" << posix_time::microsec_clock::local_time() << "] " << msg << endl;
}

// Let's make our request handling class. It must do the following:
// 1) Be derived from Fastcgipp::Request
// 2) Define the virtual response() member function from Fastcgipp::Request()

// First things first let's decide on what kind of character set we will use.
// Since we want to be able to echo all languages we will use unicode. The way this
// library handles unicode might be different than some are used to but it is done
// the way it is supposed to be. All internal characters are wide. In this case UTF-32.
// This way we don't have to mess around with variable size characters in our program.
// A string with 10 wchar_ts is ten characters long. Not up in the air as it is with UTF-8.
// Anyway, moving right along, the streams will code convert all the UTF-32 data to UTF-8
// before it is sent out to the client. This way we get the best of both worlds.
//
// So, whenever we are going to use UTF-8, our template parameter for Fastcgipp::Request<charT>
// should be wchar_t. Keep in mind that this suddendly makes
// everything wide character and utf compatible. Including HTTP header data (cookies, urls, yada-yada).

class Sf1rProcess: public Fastcgipp::Request<char>
{
	bool response()
	{
		using namespace Fastcgipp;

        if(environment().requestMethod != Http::HTTP_METHOD_GET &&
            environment().requestMethod != Http::HTTP_METHOD_POST )
        {
            out << "Status: 403 Forbidden\r\n\r\n";
            return true;
        }

        std::string requri = environment().requestUri;
        //error_log("got sf1r request: " + requri);
        if (requri.find("/sf1r") == 0)
            requri.replace(0, 5, "");
        std::string tokens = environment().findCustomHeader("HTTP_X_IZENESOFT_ACL_TOKENS");
        if (!tokens.empty())
        {
            error_log("using tokens : " + tokens);
        }
        std::string body = environment().raw_post.raw_post_data;
        if(!body.empty() && environment().raw_post.type == Http::Post<char>::raw)
        {
            //error_log("post raw data: " + body);
        }
		else
        {
            out << "Status: 400 Bad Request\r\n\r\n";
            return true;
        }

        std::string response;
        assert(driver);
        try
        {
            std::string log_content;
            rj::Document document;
            rj::Document::AllocatorType& allocator = document.GetAllocator();
            document.SetObject();
            rj::Value& top = document;
            rj::Value tag(log_tag.c_str(), log_tag.length(), allocator);
            top.AddMember("tag", tag, allocator);
            rj::Value request_body(body.c_str(), body.length(), allocator);
            top.AddMember("request", request_body, allocator);
            rj::Value request_uri(requri.c_str(), requri.length(), allocator);
            top.AddMember("uri", request_uri, allocator);
            static ptime epoch(boost::gregorian::date(1970, 1, 1));
            ptime current_time = microsec_clock::universal_time();
            time_duration td = current_time - epoch;
            std::string time_str = boost::lexical_cast<std::string>(double(td.total_milliseconds())/1000);
            rj::Value msec(time_str.c_str(), time_str.length(), allocator);
            top.AddMember("msec", msec, allocator);

            rj::StringBuffer stream;
            rj::Writer<rj::StringBuffer> writer(stream);
            document.Accept(writer);
            log_content.assign(stream.GetString(), stream.GetSize());
            boost::system::error_code ec;
            s.send_to(boost::asio::buffer(log_content.data(), log_content.size()),
                destination, 0, ec);

            if(ec)
            {
                error_log("send log to fluentd failed.");
            }

            response = driver->call(requri, tokens, body);
        }
        catch (ClientError& e) {
            error_log(std::string("ClientError: ") + e.what());
            out << "Status: 400 Bad Request\r\n\r\n";
            return true;
        } catch (ServerError& e) {
            error_log(std::string("ServerError: ") + e.what());
            out << "Status: 502 Bad GateWay\r\n\r\n";
            return true;
        } catch (RoutingError& e) {
            error_log(std::string("RoutingError: ") + e.what());
            out << "Status: 503 Service Unavailable\r\n\r\n";
            return true;
        } catch (NetworkError& e) {
            error_log(std::string("NetworkError: ") + e.what());
            out << "Status: 504 GateWay Time out\r\n\r\n";
            return true;
        } catch (std::exception& e) {
            error_log(std::string("Exception: ") + e.what());
            out << "Status: 500 Internal Server Error\r\n\r\n";
            return true;
        }

        out << "Content-Type: application/json\r\nContent-Length: " << response.size() << "\r\n\r\n";
        out.dump((const char*)response.data(), response.size());

		return true;
	}
public:
    static Sf1DriverBase* driver;
    static boost::asio::io_service io_service;
    static boost::asio::ip::udp::endpoint destination;
    static udp::socket s;
    static std::string log_tag;
};

Sf1DriverBase* Sf1rProcess::driver = NULL;
boost::asio::io_service Sf1rProcess::io_service;
udp::socket Sf1rProcess::s(Sf1rProcess::io_service);
boost::asio::ip::udp::endpoint Sf1rProcess::destination;
std::string Sf1rProcess::log_tag;

int main(int argc, char* argv[])
{
	try
	{
        if (argc < 5)
        {
            error_log("arg not enough. sf1rhost:sf1rport fluent_ip fluent_port fluent_tag ");
            return -1;
        }
        std::string host( "180.153.140.110:2181,180.153.140.111:2181,180.153.140.112:2181" );
        host = argv[1];
        std::string fluent_ip = argv[2];
        std::string fluent_port = argv[3];
        Sf1rProcess::log_tag = argv[4];
        std::string distributed;
        if(argc > 5)
        {
            distributed = argv[5];
        }
        std::string match_master;
        if (argc > 6)
        {
            match_master = argv[6];
        }
        error_log("args:" + host + "," + fluent_ip + "," + fluent_port + "," + Sf1rProcess::log_tag +
            "," + distributed + "," + match_master);
        if(distributed.empty())
        {
            Sf1Config conf;
            conf.initialSize = 2;
            conf.resize = 2;
            conf.maxSize = 4;
            conf.timeout = 30;
            Sf1rProcess::driver = new Sf1Driver(host, conf);
        }
        else
        {
            Sf1DistributedConfig dconf;
            dconf.initialSize = 2;
            dconf.resize = 2;
            dconf.maxSize = 4;
            dconf.timeout = 30;
            dconf.zkTimeout = 2000;  //ms
            dconf.match_master_name = match_master;
            Sf1rProcess::driver = new Sf1DistributedDriver(host, dconf);
            error_log("config as distributed sf1r node");
        }

        Sf1rProcess::destination.address(boost::asio::ip::address::from_string(fluent_ip));
        Sf1rProcess::destination.port(boost::lexical_cast<unsigned short>(fluent_port));
        Sf1rProcess::s.open(udp::v4());
		// First we make a Fastcgipp::Manager object, with our request handling class
		// as a template parameter.
		Fastcgipp::Manager<Sf1rProcess> fcgi;
		// Now just call the object handler function. It will sleep quietly when there
		// are no requests and efficiently manage them when there are many.
		fcgi.handler();
	}
	catch(std::exception& e)
	{
        error_log("sf1r cgi process init failed, exited.");
        error_log(e.what());
	}
    if (Sf1rProcess::driver)
        delete Sf1rProcess::driver;
    return -1;
}
<|endoftext|>


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

#ifndef _XMLOFF_XMLICTXT_HXX
#include <xmloff/xmlictxt.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif

namespace dbaxml
{
    class ODBFilter;
    class OXMLDataSource;
    class OXMLDataSourceSetting : public SvXMLImportContext
    {
        ::com::sun::star::beans::PropertyValue m_aSetting;
        ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any> m_aInfoSequence;
        OXMLDataSourceSetting* m_pContainer;
        ::com::sun::star::uno::Type m_aPropType;            // the type of the property the instance imports currently
        sal_Bool m_bIsList;

        ODBFilter& GetOwnImport();
        ::com::sun::star::uno::Any convertString(const ::com::sun::star::uno::Type& _rExpectedType, const ::rtl::OUString& _rReadCharacters);
    public:

        OXMLDataSourceSetting( ODBFilter& rImport, sal_uInt16 nPrfx,
                    const ::rtl::OUString& rLName,
                    const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList
                    ,OXMLDataSourceSetting* _pContainer = NULL);
        virtual ~OXMLDataSourceSetting();

        virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
                    const ::rtl::OUString& rLocalName,
                    const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );

        virtual void EndElement();

        virtual void Characters( const ::rtl::OUString& rChars );

        /** adds value to property
            @param  _sValue
                The value to add.
        */
        void addValue(const ::rtl::OUString& _sValue);
    };
// -----------------------------------------------------------------------------
} // namespace dbaxml
// -----------------------------------------------------------------------------

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

#ifndef _XMLOFF_XMLICTXT_HXX
#include <xmloff/xmlictxt.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif

namespace dbaxml
{
    class ODBFilter;
    class OXMLDataSource;
    class OXMLDataSourceSetting : public SvXMLImportContext
    {
        ::com::sun::star::beans::PropertyValue m_aSetting;
        ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any> m_aInfoSequence;
        OXMLDataSourceSetting* m_pContainer;
        ::com::sun::star::uno::Type m_aPropType;            // the type of the property the instance imports currently
        sal_Bool m_bIsList;

        ODBFilter& GetOwnImport();
        ::com::sun::star::uno::Any convertString(const ::com::sun::star::uno::Type& _rExpectedType, const ::rtl::OUString& _rReadCharacters);
    public:

        OXMLDataSourceSetting( ODBFilter& rImport, sal_uInt16 nPrfx,
                    const ::rtl::OUString& rLName,
                    const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList
                    ,OXMLDataSourceSetting* _pContainer = NULL);
        virtual ~OXMLDataSourceSetting();

        virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
                    const ::rtl::OUString& rLocalName,
                    const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );

        virtual void EndElement();

        virtual void Characters( const ::rtl::OUString& rChars );

        /** adds value to property
            @param  _sValue
                The value to add.
        */
        void addValue(const ::rtl::OUString& _sValue);
    };
// -----------------------------------------------------------------------------
} // namespace dbaxml
// -----------------------------------------------------------------------------

#endif // DBA_XMLDATASOURCESETTING_HXX
<|endoftext|>


<commit_before>//-----------------------------------------------------------
//
//    Copyright (C) 2015 by the deal.II authors
//
//    This file is part of the deal.II library.
//
//    The deal.II library is free software; you can use it, 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.
//    The full text of the license can be found in the file LICENSE at
//    the top level of the deal.II distribution.
//
//-----------------------------------------------------------

#include <deal.II/sundials/ida.h>
#include <deal.II/base/config.h>

#ifdef DEAL_II_WITH_SUNDIALS

#include <deal.II/base/utilities.h>
#include <deal.II/lac/block_vector.h>
#ifdef DEAL_II_WITH_TRILINOS
#include <deal.II/lac/trilinos_parallel_block_vector.h>
#include <deal.II/lac/trilinos_vector.h>
#endif
#ifdef DEAL_II_WITH_PETSC
#include <deal.II/lac/petsc_parallel_block_vector.h>
#include <deal.II/lac/petsc_parallel_vector.h>
#endif
#include <deal.II/base/utilities.h>
#include <deal.II/sundials/copy.h>

#include <iostream>
#include <iomanip>
#include <ida/ida_impl.h>

DEAL_II_NAMESPACE_OPEN

namespace SUNDIALS
{
  using namespace internal;

  namespace
  {
    template<typename VectorType>
    int t_dae_residual(realtype tt, N_Vector yy, N_Vector yp,
                       N_Vector rr, void *user_data)
    {
      IDA<VectorType> &solver = *static_cast<IDA<VectorType> *>(user_data);
      GrowingVectorMemory<VectorType> mem;

      VectorType *src_yy = mem.alloc();
      solver.reinit_vector(*src_yy);

      VectorType *src_yp = mem.alloc();
      solver.reinit_vector(*src_yp);

      VectorType *residual = mem.alloc();
      solver.reinit_vector(*residual);

      copy(*src_yy, yy);
      copy(*src_yp, yp);

      int err = solver.residual(tt, *src_yy, *src_yp, *residual);

      copy(rr, *residual);

      mem.free(src_yy);
      mem.free(src_yp);
      mem.free(residual);

      return err;
    }

    template<typename VectorType>
    int t_dae_lsetup(IDAMem IDA_mem,
                     N_Vector yy,
                     N_Vector yp,
                     N_Vector resp,
                     N_Vector tmp1,
                     N_Vector tmp2,
                     N_Vector tmp3)
    {
      (void) tmp1;
      (void) tmp2;
      (void) tmp3;
      (void) resp;
      IDA<VectorType> &solver = *static_cast<IDA<VectorType> *>(IDA_mem->ida_user_data);
      GrowingVectorMemory<VectorType> mem;

      VectorType *src_yy = mem.alloc();
      solver.reinit_vector(*src_yy);

      VectorType *src_yp = mem.alloc();
      solver.reinit_vector(*src_yp);

      copy(*src_yy, yy);
      copy(*src_yp, yp);

      int err = solver.setup_jacobian(IDA_mem->ida_tn,
                                      *src_yy,
                                      *src_yp,
                                      IDA_mem->ida_cj);

      mem.free(src_yy);
      mem.free(src_yp);

      return err;
    }

    template<typename VectorType>
    int t_dae_solve(IDAMem IDA_mem,
                    N_Vector b,
                    N_Vector weight,
                    N_Vector yy,
                    N_Vector yp,
                    N_Vector resp)
    {
      (void) weight;
      (void) yy;
      (void) yp;
      (void) resp;
      IDA<VectorType> &solver = *static_cast<IDA<VectorType> *>(IDA_mem->ida_user_data);
      GrowingVectorMemory<VectorType> mem;

      VectorType *src = mem.alloc();
      solver.reinit_vector(*src);

      VectorType *dst = mem.alloc();
      solver.reinit_vector(*dst);

      copy(*src, b);

      int err = solver.solve_jacobian_system(*src,*dst);
      copy(b, *dst);

      mem.free(src);
      mem.free(dst);

      return err;
    }

  }

  template <typename VectorType>
  IDA<VectorType>::IDA(const MPI_Comm mpi_comm, const AdditionalData &data) :
    data(data),
    ida_mem(nullptr),
    communicator(Utilities::MPI::duplicate_communicator(mpi_comm))
  {
    set_functions_to_trigger_an_assert();
  }

  template <typename VectorType>
  IDA<VectorType>::~IDA()
  {
    if (ida_mem)
      IDAFree(&ida_mem);
    MPI_Comm_free(&communicator);
  }

  template <typename VectorType>
  unsigned int IDA<VectorType>::solve_dae(VectorType &solution,
                                          VectorType &solution_dot)
  {

    unsigned int system_size = solution.size();
    unsigned int local_system_size = system_size;

    double t = data.initial_time;
    double h = data.initial_step_size;
    unsigned int step_number = 0;

    int status;

    // The solution is stored in
    // solution. Here we take only a
    // view of it.
#ifdef DEAL_II_WITH_MPI
    if (is_serial_vector<VectorType>::value == false)
      {
        IndexSet is = solution.locally_owned_elements();
        local_system_size = is.n_elements();

        yy        = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

        yp        = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

        diff_id   = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

        abs_tolls = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);
      }
    else
#endif
      {
        Assert(is_serial_vector<VectorType>::value,
               ExcInternalError("Trying to use a serial code with a parallel vector."));
        yy        = N_VNew_Serial(system_size);
        yp        = N_VNew_Serial(system_size);
        diff_id   = N_VNew_Serial(system_size);
        abs_tolls = N_VNew_Serial(system_size);
      }
    reset(data.initial_time,
          data.initial_step_size,
          solution,
          solution_dot);

    double next_time = data.initial_time;

    output_step( 0, solution, solution_dot, 0);

    while (t<data.final_time)
      {

        next_time += data.output_period;

        status = IDASolve(ida_mem, next_time, &t, yy, yp, IDA_NORMAL);
        AssertIDA(status);

        status = IDAGetLastStep(ida_mem, &h);
        AssertIDA(status);

        copy(solution, yy);
        copy(solution_dot, yp);

        while (solver_should_restart(t, solution, solution_dot))
          reset(t, h, solution, solution_dot);

        step_number++;

        output_step(t, solution, solution_dot, step_number);
      }

    // Free the vectors which are no longer used.
#ifdef DEAL_II_WITH_MPI
    if (is_serial_vector<VectorType>::value == false)
      {
        N_VDestroy_Parallel(yy);
        N_VDestroy_Parallel(yp);
        N_VDestroy_Parallel(abs_tolls);
        N_VDestroy_Parallel(diff_id);
      }
    else
#endif
      {
        N_VDestroy_Serial(yy);
        N_VDestroy_Serial(yp);
        N_VDestroy_Serial(abs_tolls);
        N_VDestroy_Serial(diff_id);
      }

    return step_number;
  }

  template <typename VectorType>
  void IDA<VectorType>::reset(const double &current_time,
                              const double &current_time_step,
                              VectorType &solution,
                              VectorType &solution_dot)
  {

    unsigned int system_size;
    unsigned int local_system_size;
    bool first_step = (current_time == data.initial_time);

    if (ida_mem)
      IDAFree(&ida_mem);

    ida_mem = IDACreate();

    // Free the vectors which are no longer used.
    if (yy)
      {
#ifdef DEAL_II_WITH_MPI
        if (is_serial_vector<VectorType>::value == false)
          {
            N_VDestroy_Parallel(yy);
            N_VDestroy_Parallel(yp);
            N_VDestroy_Parallel(abs_tolls);
            N_VDestroy_Parallel(diff_id);
          }
        else
#endif
          {
            N_VDestroy_Serial(yy);
            N_VDestroy_Serial(yp);
            N_VDestroy_Serial(abs_tolls);
            N_VDestroy_Serial(diff_id);
          }
      }

    int status;
    system_size = solution.size();
#ifdef DEAL_II_WITH_MPI
    if (is_serial_vector<VectorType>::value == false)
      {
        IndexSet is = solution.locally_owned_elements();
        local_system_size = is.n_elements();

        yy        = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

        yp        = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

        diff_id   = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

        abs_tolls = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

      }
    else
#endif
      {
        yy        = N_VNew_Serial(system_size);
        yp        = N_VNew_Serial(system_size);
        diff_id   = N_VNew_Serial(system_size);
        abs_tolls = N_VNew_Serial(system_size);
      }

    copy(yy, solution);
    copy(yp, solution_dot);

    status = IDAInit(ida_mem, t_dae_residual<VectorType>, current_time, yy, yp);
    AssertIDA(status);

    if (data.use_local_tolerances)
      {
        copy(abs_tolls, get_local_tolerances());
        status = IDASVtolerances(ida_mem, data.relative_tolerance, abs_tolls);
        AssertIDA(status);
      }
    else
      {
        status = IDASStolerances(ida_mem, data.relative_tolerance, data.absolute_tolerance);
        AssertIDA(status);
      }

    status = IDASetInitStep(ida_mem, current_time_step);
    AssertIDA(status);

    status = IDASetUserData(ida_mem, (void *) this);
    AssertIDA(status);

    if (data.ic_type == AdditionalData::use_y_diff ||
        data.reset_type == AdditionalData::use_y_diff  ||
        data.ignore_algebraic_terms_for_errors)
      {
        VectorType diff_comp_vector(solution);
        diff_comp_vector = 0.0;
        auto dc = differential_components();
        for (auto i = dc.begin(); i != dc.end(); ++i)
          diff_comp_vector[*i] = 1.0;

        copy(diff_id, diff_comp_vector);
        status = IDASetId(ida_mem, diff_id);
        AssertIDA(status);
      }

    status = IDASetSuppressAlg(ida_mem, data.ignore_algebraic_terms_for_errors);
    AssertIDA(status);

//  status = IDASetMaxNumSteps(ida_mem, max_steps);
    status = IDASetStopTime(ida_mem, data.final_time);
    AssertIDA(status);

    status = IDASetMaxNonlinIters(ida_mem, data.maximum_non_linear_iterations);
    AssertIDA(status);

    // Initialize solver
    IDAMem IDA_mem;
    IDA_mem = (IDAMem) ida_mem;

    IDA_mem->ida_lsetup = t_dae_lsetup<VectorType>;
    IDA_mem->ida_lsolve = t_dae_solve<VectorType>;
    IDA_mem->ida_setupNonNull = true;

    status = IDASetMaxOrd(ida_mem, data.maximum_order);
    AssertIDA(status);

    typename AdditionalData::InitialConditionCorrection  type;
    if (first_step)
      type = data.ic_type;
    else
      type = data.reset_type;

    status = IDASetMaxNumItersIC(ida_mem, data.maximum_non_linear_iterations_ic);
    AssertIDA(status);

    if (type == AdditionalData::use_y_dot)
      {
        // (re)initialization of the vectors
        status = IDACalcIC(ida_mem, IDA_Y_INIT, current_time+current_time_step);
        AssertIDA(status);

        status = IDAGetConsistentIC(ida_mem, yy, yp);
        AssertIDA(status);

        copy(solution, yy);
        copy(solution_dot, yp);
      }
    else if (type == AdditionalData::use_y_diff)
      {
        status = IDACalcIC(ida_mem, IDA_YA_YDP_INIT, current_time+current_time_step);
        AssertIDA(status);

        status = IDAGetConsistentIC(ida_mem, yy, yp);
        AssertIDA(status);

        copy(solution, yy);
        copy(solution_dot, yp);
      }
  }

  template<typename VectorType>
  void IDA<VectorType>::set_functions_to_trigger_an_assert()
  {

    reinit_vector = [](VectorType &)
    {
      AssertThrow(false, ExcFunctionNotProvided("reinit_vector"));
    };

    residual = [](const double,
                  const VectorType &,
                  const VectorType &,
                  VectorType &) ->int
    {
      int ret=0;
      AssertThrow(false,  ExcFunctionNotProvided("residual"));
      return ret;
    };

    setup_jacobian = [](const double,
                        const VectorType &,
                        const VectorType &,
                        const double) ->int
    {
      int ret=0;
      AssertThrow(false, ExcFunctionNotProvided("setup_jacobian"));
      return ret;
    };

    solve_jacobian_system = [](const VectorType &,
                               VectorType &) ->int
    {
      int ret=0;
      AssertThrow(false, ExcFunctionNotProvided("solve_jacobian_system"));
      return ret;
    };

    output_step = [](const double,
                     const VectorType &,
                     const VectorType &,
                     const unsigned int)
    {
      return;
    };

    solver_should_restart = [](const double,
                               VectorType &,
                               VectorType &) ->bool
    {
      return false;
    };

    differential_components = [&]() ->IndexSet
    {
      GrowingVectorMemory<VectorType> mem;
      auto v = mem.alloc();
      reinit_vector(*v);
      unsigned int size = v->size();
      mem.free(v);
      return complete_index_set(size);
    };

    get_local_tolerances = []() ->VectorType &
    {
      std::shared_ptr<VectorType> y;
      AssertThrow(false, ExcFunctionNotProvided("get_local_tolerances"));
      return *y;
    };
  }

  template class IDA<Vector<double> >;
  template class IDA<BlockVector<double> >;

#ifdef DEAL_II_WITH_MPI

#ifdef DEAL_II_WITH_TRILINOS
  template class IDA<TrilinosWrappers::MPI::Vector>;
  template class IDA<TrilinosWrappers::MPI::BlockVector>;
#endif

#ifdef DEAL_II_WITH_PETSC
  template class IDA<PETScWrappers::MPI::Vector>;
  template class IDA<PETScWrappers::MPI::BlockVector>;
#endif

#endif

}

DEAL_II_NAMESPACE_CLOSE

#endif
<commit_msg>Get rid of two unused variable warnings.<commit_after>//-----------------------------------------------------------
//
//    Copyright (C) 2015 by the deal.II authors
//
//    This file is part of the deal.II library.
//
//    The deal.II library is free software; you can use it, 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.
//    The full text of the license can be found in the file LICENSE at
//    the top level of the deal.II distribution.
//
//-----------------------------------------------------------

#include <deal.II/sundials/ida.h>
#include <deal.II/base/config.h>

#ifdef DEAL_II_WITH_SUNDIALS

#include <deal.II/base/utilities.h>
#include <deal.II/lac/block_vector.h>
#ifdef DEAL_II_WITH_TRILINOS
#include <deal.II/lac/trilinos_parallel_block_vector.h>
#include <deal.II/lac/trilinos_vector.h>
#endif
#ifdef DEAL_II_WITH_PETSC
#include <deal.II/lac/petsc_parallel_block_vector.h>
#include <deal.II/lac/petsc_parallel_vector.h>
#endif
#include <deal.II/base/utilities.h>
#include <deal.II/sundials/copy.h>

#include <iostream>
#include <iomanip>
#include <ida/ida_impl.h>

DEAL_II_NAMESPACE_OPEN

namespace SUNDIALS
{
  using namespace internal;

  namespace
  {
    template<typename VectorType>
    int t_dae_residual(realtype tt, N_Vector yy, N_Vector yp,
                       N_Vector rr, void *user_data)
    {
      IDA<VectorType> &solver = *static_cast<IDA<VectorType> *>(user_data);
      GrowingVectorMemory<VectorType> mem;

      VectorType *src_yy = mem.alloc();
      solver.reinit_vector(*src_yy);

      VectorType *src_yp = mem.alloc();
      solver.reinit_vector(*src_yp);

      VectorType *residual = mem.alloc();
      solver.reinit_vector(*residual);

      copy(*src_yy, yy);
      copy(*src_yp, yp);

      int err = solver.residual(tt, *src_yy, *src_yp, *residual);

      copy(rr, *residual);

      mem.free(src_yy);
      mem.free(src_yp);
      mem.free(residual);

      return err;
    }

    template<typename VectorType>
    int t_dae_lsetup(IDAMem IDA_mem,
                     N_Vector yy,
                     N_Vector yp,
                     N_Vector resp,
                     N_Vector tmp1,
                     N_Vector tmp2,
                     N_Vector tmp3)
    {
      (void) tmp1;
      (void) tmp2;
      (void) tmp3;
      (void) resp;
      IDA<VectorType> &solver = *static_cast<IDA<VectorType> *>(IDA_mem->ida_user_data);
      GrowingVectorMemory<VectorType> mem;

      VectorType *src_yy = mem.alloc();
      solver.reinit_vector(*src_yy);

      VectorType *src_yp = mem.alloc();
      solver.reinit_vector(*src_yp);

      copy(*src_yy, yy);
      copy(*src_yp, yp);

      int err = solver.setup_jacobian(IDA_mem->ida_tn,
                                      *src_yy,
                                      *src_yp,
                                      IDA_mem->ida_cj);

      mem.free(src_yy);
      mem.free(src_yp);

      return err;
    }

    template<typename VectorType>
    int t_dae_solve(IDAMem IDA_mem,
                    N_Vector b,
                    N_Vector weight,
                    N_Vector yy,
                    N_Vector yp,
                    N_Vector resp)
    {
      (void) weight;
      (void) yy;
      (void) yp;
      (void) resp;
      IDA<VectorType> &solver = *static_cast<IDA<VectorType> *>(IDA_mem->ida_user_data);
      GrowingVectorMemory<VectorType> mem;

      VectorType *src = mem.alloc();
      solver.reinit_vector(*src);

      VectorType *dst = mem.alloc();
      solver.reinit_vector(*dst);

      copy(*src, b);

      int err = solver.solve_jacobian_system(*src,*dst);
      copy(b, *dst);

      mem.free(src);
      mem.free(dst);

      return err;
    }

  }

  template <typename VectorType>
  IDA<VectorType>::IDA(const MPI_Comm mpi_comm, const AdditionalData &data) :
    data(data),
    ida_mem(nullptr),
    communicator(Utilities::MPI::duplicate_communicator(mpi_comm))
  {
    set_functions_to_trigger_an_assert();
  }

  template <typename VectorType>
  IDA<VectorType>::~IDA()
  {
    if (ida_mem)
      IDAFree(&ida_mem);
    MPI_Comm_free(&communicator);
  }

  template <typename VectorType>
  unsigned int IDA<VectorType>::solve_dae(VectorType &solution,
                                          VectorType &solution_dot)
  {

    unsigned int system_size = solution.size();
    unsigned int local_system_size = system_size;

    double t = data.initial_time;
    double h = data.initial_step_size;
    unsigned int step_number = 0;

    int status;
    (void)status;

    // The solution is stored in
    // solution. Here we take only a
    // view of it.
#ifdef DEAL_II_WITH_MPI
    if (is_serial_vector<VectorType>::value == false)
      {
        IndexSet is = solution.locally_owned_elements();
        local_system_size = is.n_elements();

        yy        = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

        yp        = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

        diff_id   = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

        abs_tolls = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);
      }
    else
#endif
      {
        Assert(is_serial_vector<VectorType>::value,
               ExcInternalError("Trying to use a serial code with a parallel vector."));
        yy        = N_VNew_Serial(system_size);
        yp        = N_VNew_Serial(system_size);
        diff_id   = N_VNew_Serial(system_size);
        abs_tolls = N_VNew_Serial(system_size);
      }
    reset(data.initial_time,
          data.initial_step_size,
          solution,
          solution_dot);

    double next_time = data.initial_time;

    output_step( 0, solution, solution_dot, 0);

    while (t<data.final_time)
      {

        next_time += data.output_period;

        status = IDASolve(ida_mem, next_time, &t, yy, yp, IDA_NORMAL);
        AssertIDA(status);

        status = IDAGetLastStep(ida_mem, &h);
        AssertIDA(status);

        copy(solution, yy);
        copy(solution_dot, yp);

        while (solver_should_restart(t, solution, solution_dot))
          reset(t, h, solution, solution_dot);

        step_number++;

        output_step(t, solution, solution_dot, step_number);
      }

    // Free the vectors which are no longer used.
#ifdef DEAL_II_WITH_MPI
    if (is_serial_vector<VectorType>::value == false)
      {
        N_VDestroy_Parallel(yy);
        N_VDestroy_Parallel(yp);
        N_VDestroy_Parallel(abs_tolls);
        N_VDestroy_Parallel(diff_id);
      }
    else
#endif
      {
        N_VDestroy_Serial(yy);
        N_VDestroy_Serial(yp);
        N_VDestroy_Serial(abs_tolls);
        N_VDestroy_Serial(diff_id);
      }

    return step_number;
  }

  template <typename VectorType>
  void IDA<VectorType>::reset(const double &current_time,
                              const double &current_time_step,
                              VectorType &solution,
                              VectorType &solution_dot)
  {

    unsigned int system_size;
    unsigned int local_system_size;
    bool first_step = (current_time == data.initial_time);

    if (ida_mem)
      IDAFree(&ida_mem);

    ida_mem = IDACreate();

    // Free the vectors which are no longer used.
    if (yy)
      {
#ifdef DEAL_II_WITH_MPI
        if (is_serial_vector<VectorType>::value == false)
          {
            N_VDestroy_Parallel(yy);
            N_VDestroy_Parallel(yp);
            N_VDestroy_Parallel(abs_tolls);
            N_VDestroy_Parallel(diff_id);
          }
        else
#endif
          {
            N_VDestroy_Serial(yy);
            N_VDestroy_Serial(yp);
            N_VDestroy_Serial(abs_tolls);
            N_VDestroy_Serial(diff_id);
          }
      }

    int status;
    (void)status;
    system_size = solution.size();
#ifdef DEAL_II_WITH_MPI
    if (is_serial_vector<VectorType>::value == false)
      {
        IndexSet is = solution.locally_owned_elements();
        local_system_size = is.n_elements();

        yy        = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

        yp        = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

        diff_id   = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

        abs_tolls = N_VNew_Parallel(communicator,
                                    local_system_size,
                                    system_size);

      }
    else
#endif
      {
        yy        = N_VNew_Serial(system_size);
        yp        = N_VNew_Serial(system_size);
        diff_id   = N_VNew_Serial(system_size);
        abs_tolls = N_VNew_Serial(system_size);
      }

    copy(yy, solution);
    copy(yp, solution_dot);

    status = IDAInit(ida_mem, t_dae_residual<VectorType>, current_time, yy, yp);
    AssertIDA(status);

    if (data.use_local_tolerances)
      {
        copy(abs_tolls, get_local_tolerances());
        status = IDASVtolerances(ida_mem, data.relative_tolerance, abs_tolls);
        AssertIDA(status);
      }
    else
      {
        status = IDASStolerances(ida_mem, data.relative_tolerance, data.absolute_tolerance);
        AssertIDA(status);
      }

    status = IDASetInitStep(ida_mem, current_time_step);
    AssertIDA(status);

    status = IDASetUserData(ida_mem, (void *) this);
    AssertIDA(status);

    if (data.ic_type == AdditionalData::use_y_diff ||
        data.reset_type == AdditionalData::use_y_diff  ||
        data.ignore_algebraic_terms_for_errors)
      {
        VectorType diff_comp_vector(solution);
        diff_comp_vector = 0.0;
        auto dc = differential_components();
        for (auto i = dc.begin(); i != dc.end(); ++i)
          diff_comp_vector[*i] = 1.0;

        copy(diff_id, diff_comp_vector);
        status = IDASetId(ida_mem, diff_id);
        AssertIDA(status);
      }

    status = IDASetSuppressAlg(ida_mem, data.ignore_algebraic_terms_for_errors);
    AssertIDA(status);

//  status = IDASetMaxNumSteps(ida_mem, max_steps);
    status = IDASetStopTime(ida_mem, data.final_time);
    AssertIDA(status);

    status = IDASetMaxNonlinIters(ida_mem, data.maximum_non_linear_iterations);
    AssertIDA(status);

    // Initialize solver
    IDAMem IDA_mem;
    IDA_mem = (IDAMem) ida_mem;

    IDA_mem->ida_lsetup = t_dae_lsetup<VectorType>;
    IDA_mem->ida_lsolve = t_dae_solve<VectorType>;
    IDA_mem->ida_setupNonNull = true;

    status = IDASetMaxOrd(ida_mem, data.maximum_order);
    AssertIDA(status);

    typename AdditionalData::InitialConditionCorrection  type;
    if (first_step)
      type = data.ic_type;
    else
      type = data.reset_type;

    status = IDASetMaxNumItersIC(ida_mem, data.maximum_non_linear_iterations_ic);
    AssertIDA(status);

    if (type == AdditionalData::use_y_dot)
      {
        // (re)initialization of the vectors
        status = IDACalcIC(ida_mem, IDA_Y_INIT, current_time+current_time_step);
        AssertIDA(status);

        status = IDAGetConsistentIC(ida_mem, yy, yp);
        AssertIDA(status);

        copy(solution, yy);
        copy(solution_dot, yp);
      }
    else if (type == AdditionalData::use_y_diff)
      {
        status = IDACalcIC(ida_mem, IDA_YA_YDP_INIT, current_time+current_time_step);
        AssertIDA(status);

        status = IDAGetConsistentIC(ida_mem, yy, yp);
        AssertIDA(status);

        copy(solution, yy);
        copy(solution_dot, yp);
      }
  }

  template<typename VectorType>
  void IDA<VectorType>::set_functions_to_trigger_an_assert()
  {

    reinit_vector = [](VectorType &)
    {
      AssertThrow(false, ExcFunctionNotProvided("reinit_vector"));
    };

    residual = [](const double,
                  const VectorType &,
                  const VectorType &,
                  VectorType &) ->int
    {
      int ret=0;
      AssertThrow(false,  ExcFunctionNotProvided("residual"));
      return ret;
    };

    setup_jacobian = [](const double,
                        const VectorType &,
                        const VectorType &,
                        const double) ->int
    {
      int ret=0;
      AssertThrow(false, ExcFunctionNotProvided("setup_jacobian"));
      return ret;
    };

    solve_jacobian_system = [](const VectorType &,
                               VectorType &) ->int
    {
      int ret=0;
      AssertThrow(false, ExcFunctionNotProvided("solve_jacobian_system"));
      return ret;
    };

    output_step = [](const double,
                     const VectorType &,
                     const VectorType &,
                     const unsigned int)
    {
      return;
    };

    solver_should_restart = [](const double,
                               VectorType &,
                               VectorType &) ->bool
    {
      return false;
    };

    differential_components = [&]() ->IndexSet
    {
      GrowingVectorMemory<VectorType> mem;
      auto v = mem.alloc();
      reinit_vector(*v);
      unsigned int size = v->size();
      mem.free(v);
      return complete_index_set(size);
    };

    get_local_tolerances = []() ->VectorType &
    {
      std::shared_ptr<VectorType> y;
      AssertThrow(false, ExcFunctionNotProvided("get_local_tolerances"));
      return *y;
    };
  }

  template class IDA<Vector<double> >;
  template class IDA<BlockVector<double> >;

#ifdef DEAL_II_WITH_MPI

#ifdef DEAL_II_WITH_TRILINOS
  template class IDA<TrilinosWrappers::MPI::Vector>;
  template class IDA<TrilinosWrappers::MPI::BlockVector>;
#endif

#ifdef DEAL_II_WITH_PETSC
  template class IDA<PETScWrappers::MPI::Vector>;
  template class IDA<PETScWrappers::MPI::BlockVector>;
#endif

#endif

}

DEAL_II_NAMESPACE_CLOSE

#endif
<|endoftext|>


<commit_before>/*
For more information, please see: http://software.sci.utah.edu

The MIT License

Copyright (c) 2012 Scientific Computing and Imaging Institute,
University of Utah.

License for the specific language governing rights and limitations under
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/

#include <Modules/Factory/ModuleDescriptionLookup.h>
#include <Modules/Basic/ReceiveScalar.h>
#include <Modules/Basic/SendScalar.h>
#include <Modules/Basic/ReceiveTestMatrix.h>
#include <Modules/Basic/SendTestMatrix.h>
#include <Modules/Basic/DynamicPortTester.h>
#include <Modules/Legacy/Bundle/GetFieldsFromBundle.h>
#include <Modules/Legacy/Bundle/GetMatricesFromBundle.h>
#include <Modules/Legacy/Bundle/InsertFieldsIntoBundle.h>
#include <Modules/Legacy/Bundle/InsertMatricesIntoBundle.h>
#include <Modules/Legacy/Fields/SplitFieldByDomain.h>
#include <Modules/Basic/PrintDatatype.h>
#include <Modules/Math/EvaluateLinearAlgebraUnary.h>
#include <Modules/Math/EvaluateLinearAlgebraBinary.h>
#include <Modules/Math/ReportMatrixInfo.h>
#include <Modules/Math/AppendMatrix.h>
#include <Modules/Math/CreateMatrix.h>
#include <Modules/Math/GetMatrixSlice.h>
#include <Modules/Math/SolveLinearSystem.h>
#include <Modules/Fields/ReportFieldInfo.h>
#include <Modules/Legacy/Fields/CreateLatVol.h>
#include <Modules/Legacy/Fields/GetFieldBoundary.h>
#include <Modules/Legacy/Fields/CalculateSignedDistanceToField.h>
#include <Modules/Legacy/Fields/CalculateGradients.h>
#include <Modules/Legacy/Fields/ConvertQuadSurfToTriSurf.h>
#include <Modules/Legacy/Fields/AlignMeshBoundingBoxes.h>
#include <Modules/Legacy/Fields/GetFieldNodes.h>
#include <Modules/Legacy/Fields/SetFieldNodes.h>
#include <Modules/Legacy/Fields/GetDomainBoundary.h>
#include <Modules/Legacy/Fields/JoinFields.h>
#include <Modules/Legacy/Fields/SplitFieldByDomain.h>
#include <Modules/Legacy/Fields/CreateFieldData.h>
#include <Modules/Legacy/Fields/CalculateFieldData5.h>
#include <Modules/Legacy/Fields/SplitFieldByDomain.h>
#include <Modules/Legacy/Fields/GetFieldData.h>
#include <Modules/Legacy/Fields/SetFieldData.h>
#include <Modules/Legacy/Fields/ResampleRegularMesh.h>
#include <Modules/Legacy/Fields/FairMesh.h>
#include <Modules/Legacy/Fields/ConvertFieldBasis.h>
#include <Modules/Legacy/Fields/ScaleFieldMeshAndData.h>
#include <Modules/Legacy/Fields/ProjectPointsOntoMesh.h>
#include <Modules/Legacy/Fields/CalculateDistanceToField.h>
#include <Modules/Legacy/Fields/CalculateDistanceToFieldBoundary.h>
#include <Modules/Legacy/Fields/MapFieldDataOntoElems.h>
#include <Modules/Legacy/Fields/MapFieldDataOntoNodes.h>
#include <Modules/Legacy/Fields/ClipFieldByFunction3.h>
#include <Modules/Legacy/Fields/MapFieldDataFromSourceToDestination.h>
#include <Modules/Legacy/Math/SolveMinNormLeastSqSystem.h>
#include <Modules/Legacy/Matlab/DataIO/ImportDatatypesFromMatlab.h>
#include <Modules/DataIO/ReadMatrix.h>
#include <Modules/DataIO/WriteMatrix.h>
#include <Modules/DataIO/ReadField.h>
#include <Modules/DataIO/WriteField.h>
#include <Modules/String/CreateString.h>
#include <Modules/String/NetworkNotes.h>
#include <Modules/Visualization/ShowString.h>
#include <Modules/Visualization/ShowField.h>
#include <Modules/Visualization/CreateBasicColorMap.h>
#include <Modules/FiniteElements/TDCSSimulator.h>
#include <Modules/Render/ViewScene.h>
#include <Modules/Legacy/FiniteElements/BuildFEMatrix.h>
#include <Modules/Basic/AsyncPortTestModule.h>
#include <Modules/Basic/NeedToExecuteTester.h>
//#include <Modules/Fields/@ModuleName@.h>

using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Modules::Factory;
using namespace SCIRun::Modules::Bundles;
using namespace SCIRun::Modules::Fields;
using namespace SCIRun::Modules::Basic;
using namespace SCIRun::Modules::Math;
using namespace SCIRun::Modules::FiniteElements;
using namespace SCIRun::Modules::DataIO;
using namespace SCIRun::Modules::Matlab::DataIO;
using namespace SCIRun::Modules::StringProcessing;
using namespace SCIRun::Modules::Visualization;
using namespace SCIRun::Modules::Render;

void ModuleDescriptionLookup::addEssentialModules()
{
  addModuleDesc<ReadMatrixModule>("ReadMatrix", "DataIO", "SCIRun", "Functional, needs GUI and algorithm work.", "...");
  addModuleDesc<WriteMatrixModule>("WriteMatrix", "DataIO", "SCIRun", "Functional, outputs text files or binary .mat only.", "...");
  addModuleDesc<ReadFieldModule>("ReadField", "DataIO", "SCIRun", "Functional, needs GUI and algorithm work.", "...");
  addModuleDesc<WriteFieldModule>("WriteField", "DataIO", "SCIRun", "Functional, outputs binary .fld only.", "...");
  addModuleDesc<PrintDatatypeModule>("PrintDatatype", "String", "SCIRun", "...", "...");
  addModuleDesc<ReportMatrixInfoModule>("ReportMatrixInfo", "Math", "SCIRun", "Functional, needs GUI work.", "...");
  addModuleDesc<ReportFieldInfoModule>("ReportFieldInfo", "MiscField", "SCIRun", "Same as v4", "...");
  addModuleDesc<AppendMatrixModule>("AppendMatrix", "Math", "SCIRun", "Fully functional.", "...");
  addModuleDesc<EvaluateLinearAlgebraUnaryModule>("EvaluateLinearAlgebraUnary", "Math", "SCIRun", "Partially functional, needs GUI work.", "...");
  addModuleDesc<EvaluateLinearAlgebraBinaryModule>("EvaluateLinearAlgebraBinary", "Math", "SCIRun", "Partially functional, needs GUI work.", "...");
  addModuleDesc<CreateMatrixModule>("CreateMatrix", "Math", "SCIRun", "Functional, needs GUI work.", "...");
  addModuleDesc<SolveLinearSystemModule>("SolveLinearSystem", "Math", "SCIRun", "Four multi-threaded algorithms available.", "...");
  addModuleDesc<CreateStringModule>("CreateString", "String", "SCIRun", "Functional, needs GUI work.", "...");
	addModuleDesc<NetworkNotesModule>("NetworkNotes", "String", "SCIRun", "Functional, needs GUI work.", "...");
  //addModuleDesc<ShowStringModule>("ShowString", "String", "SCIRun", "...", "...");
  addModuleDesc<ShowFieldModule>("Some basic options available, still work in progress.", "...");
  addModuleDesc<CreateLatVol>("CreateLatVol", "NewField", "SCIRun", "Official ported v4 module.", "...");
  addModuleDesc<ViewScene>("Can display meshes and fields, pan/rotate/zoom.", "...");

  addModuleDesc<GetFieldBoundary>("GetFieldBoundary", "NewField", "SCIRun", "First real ported module", "...");
  addModuleDesc<CalculateSignedDistanceToField>("CalculateSignedDistanceToField", "ChangeFieldData", "SCIRun", "Second real ported module", "...");
  addModuleDesc<CalculateGradients>("CalculateGradients", "ChangeFieldData", "SCIRun", "Real ported module", "...");
  addModuleDesc<ConvertQuadSurfToTriSurf>("ConvertQuadSurfToTriSurf", "ChangeMesh", "SCIRun", "Real ported module", "...");
  addModuleDesc<AlignMeshBoundingBoxes>("AlignMeshBoundingBoxes", "ChangeMesh", "SCIRun", "Real ported module", "...");
  addModuleDesc<GetFieldNodes>("GetFieldNodes", "ChangeMesh", "SCIRun", "Real ported module", "...");
  addModuleDesc<SetFieldNodes>("SetFieldNodes", "ChangeMesh", "SCIRun", "Real ported module", "...");
  //addModuleDesc<TDCSSimulatorModule>("tDCSSimulator", "FiniteElements", "SCIRun", "Dummy module for design purposes", "...");
  addModuleDesc<SolveMinNormLeastSqSystem>("SolveMinNormLeastSqSystem", "Math", "SCIRun", "Real ported module", "...");
  addModuleDesc<CreateBasicColorMap>("CreateStandardColorMap", "Visualization", "SCIRun", "In progress: two color maps available", "...");
  addModuleDesc<GetDomainBoundary>("Real ported module: Many bugs and UI logic issues", "...");
  addModuleDesc<JoinFields>("Real ported module: Many bugs and UI logic issues", "...");
  addModuleDesc<CreateFieldData>("Real ported module", "...");
  addModuleDesc<CalculateFieldData>("Real ported module", "...");
  addModuleDesc<BuildFEMatrix>("BuildFEMatrix", "FiniteElements", "SCIRun", "In progress: main path through code works", "Generates stiffness matrix ");
  addModuleDesc<ResampleRegularMesh>("Real ported module", "...");
  addModuleDesc<FairMesh>("Real ported module", "...");
  //TODO: incomplete impl
  //addModuleDesc<ConvertFieldBasis>("NOT WORKING YET--Real ported module", "...");
  //addModuleDesc<ScaleFieldMeshAndData>("NOT WORKING YET--Real ported module", "...");
  addModuleDesc<ProjectPointsOntoMesh>("Real ported module", "...");
  addModuleDesc<CalculateDistanceToField>("Real ported module", "...");
  addModuleDesc<CalculateDistanceToFieldBoundary>("Real ported module", "...");
  addModuleDesc<MapFieldDataOntoNodes>("Real ported module", "...");
  addModuleDesc<MapFieldDataOntoElements>("Real ported module", "...");
  addModuleDesc<ClipFieldByFunction>("In progress", "...");
  addModuleDesc<MapFieldDataFromSourceToDestination>("Real ported module", "...");
  addModuleDesc<GetMatrixSlice>("New module based on GetRowOrColumnFromMatrix", "...");
  //addModuleDesc<ImportDatatypesFromMatlab>("Improved version of Matlab importer", "work in progress"); //not ready yet

  // insert module desc here
}

void ModuleDescriptionLookup::addBundleModules()
{
  //addModuleDesc<GetMatricesFromBundle>("Real ported module: improved UI", "...");
  //addModuleDesc<InsertMatricesIntoBundle>("Real ported module: improved UI", "...");
  //TODO: incomplete impl
  //addModuleDesc<GetFieldsFromBundle>("Real ported module: improved UI", "...");
  //addModuleDesc<InsertFieldsIntoBundle>("Real ported module: improved UI", "...");
  addModuleDesc<SplitFieldByDomain>("Real ported module", "...");
}

void ModuleDescriptionLookup::addTestingModules()
{
  addModuleDesc<SendScalarModule>("SendScalar", "Testing", "SCIRun", "Functional, needs GUI and algorithm work.", "...");
  addModuleDesc<ReceiveScalarModule>("ReceiveScalar", "Testing", "SCIRun", "...", "...");
  addModuleDesc<SendTestMatrixModule>("SendTestMatrix", "Testing", "SCIRun", "...", "...");
  addModuleDesc<ReceiveTestMatrixModule>("ReceiveTestMatrix", "Testing", "SCIRun", "...", "...");
  addModuleDesc<DynamicPortTester>("DynamicPortTester", "Testing", "SCIRun", "...", "...");
  addModuleDesc<AsyncPortTestModule>("...", "ViewScene clone");
  addModuleDesc<NeedToExecuteTester>("...", "...");
}
<commit_msg>Add to module factory<commit_after>/*
For more information, please see: http://software.sci.utah.edu

The MIT License

Copyright (c) 2012 Scientific Computing and Imaging Institute,
University of Utah.

License for the specific language governing rights and limitations under
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/

#include <Modules/Factory/ModuleDescriptionLookup.h>
#include <Modules/Basic/ReceiveScalar.h>
#include <Modules/Basic/SendScalar.h>
#include <Modules/Basic/ReceiveTestMatrix.h>
#include <Modules/Basic/SendTestMatrix.h>
#include <Modules/Basic/DynamicPortTester.h>
#include <Modules/Legacy/Bundle/GetFieldsFromBundle.h>
#include <Modules/Legacy/Bundle/GetMatricesFromBundle.h>
#include <Modules/Legacy/Bundle/InsertFieldsIntoBundle.h>
#include <Modules/Legacy/Bundle/InsertMatricesIntoBundle.h>
#include <Modules/Legacy/Fields/SplitFieldByDomain.h>
#include <Modules/Basic/PrintDatatype.h>
#include <Modules/Math/EvaluateLinearAlgebraUnary.h>
#include <Modules/Math/EvaluateLinearAlgebraBinary.h>
#include <Modules/Math/ReportMatrixInfo.h>
#include <Modules/Math/AppendMatrix.h>
#include <Modules/Math/CreateMatrix.h>
#include <Modules/Math/GetMatrixSlice.h>
#include <Modules/Math/SolveLinearSystem.h>
#include <Modules/Fields/ReportFieldInfo.h>
#include <Modules/Legacy/Fields/CreateLatVol.h>
#include <Modules/Legacy/Fields/GetFieldBoundary.h>
#include <Modules/Legacy/Fields/CalculateSignedDistanceToField.h>
#include <Modules/Legacy/Fields/CalculateGradients.h>
#include <Modules/Legacy/Fields/ConvertQuadSurfToTriSurf.h>
#include <Modules/Legacy/Fields/AlignMeshBoundingBoxes.h>
#include <Modules/Legacy/Fields/GetFieldNodes.h>
#include <Modules/Legacy/Fields/SetFieldNodes.h>
#include <Modules/Legacy/Fields/GetDomainBoundary.h>
#include <Modules/Legacy/Fields/JoinFields.h>
#include <Modules/Legacy/Fields/SplitFieldByDomain.h>
#include <Modules/Legacy/Fields/CreateFieldData.h>
#include <Modules/Legacy/Fields/CalculateFieldData5.h>
#include <Modules/Legacy/Fields/SplitFieldByDomain.h>
#include <Modules/Legacy/Fields/GetFieldData.h>
#include <Modules/Legacy/Fields/SetFieldData.h>
#include <Modules/Legacy/Fields/ResampleRegularMesh.h>
#include <Modules/Legacy/Fields/FairMesh.h>
#include <Modules/Legacy/Fields/ConvertFieldBasis.h>
#include <Modules/Legacy/Fields/ScaleFieldMeshAndData.h>
#include <Modules/Legacy/Fields/ProjectPointsOntoMesh.h>
#include <Modules/Legacy/Fields/CalculateDistanceToField.h>
#include <Modules/Legacy/Fields/CalculateDistanceToFieldBoundary.h>
#include <Modules/Legacy/Fields/MapFieldDataOntoElems.h>
#include <Modules/Legacy/Fields/MapFieldDataOntoNodes.h>
#include <Modules/Legacy/Fields/ClipFieldByFunction3.h>
#include <Modules/Legacy/Fields/MapFieldDataFromSourceToDestination.h>
#include <Modules/Legacy/Fields/SetFieldDataToConstantValue.h>
#include <Modules/Legacy/Math/SolveMinNormLeastSqSystem.h>
#include <Modules/Legacy/Matlab/DataIO/ImportDatatypesFromMatlab.h>
#include <Modules/DataIO/ReadMatrix.h>
#include <Modules/DataIO/WriteMatrix.h>
#include <Modules/DataIO/ReadField.h>
#include <Modules/DataIO/WriteField.h>
#include <Modules/String/CreateString.h>
#include <Modules/String/NetworkNotes.h>
#include <Modules/Visualization/ShowString.h>
#include <Modules/Visualization/ShowField.h>
#include <Modules/Visualization/CreateBasicColorMap.h>
#include <Modules/FiniteElements/TDCSSimulator.h>
#include <Modules/Render/ViewScene.h>
#include <Modules/Legacy/FiniteElements/BuildFEMatrix.h>
#include <Modules/Basic/AsyncPortTestModule.h>
#include <Modules/Basic/NeedToExecuteTester.h>
//#include <Modules/Fields/@ModuleName@.h>

using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Modules::Factory;
using namespace SCIRun::Modules::Bundles;
using namespace SCIRun::Modules::Fields;
using namespace SCIRun::Modules::Basic;
using namespace SCIRun::Modules::Math;
using namespace SCIRun::Modules::FiniteElements;
using namespace SCIRun::Modules::DataIO;
using namespace SCIRun::Modules::Matlab::DataIO;
using namespace SCIRun::Modules::StringProcessing;
using namespace SCIRun::Modules::Visualization;
using namespace SCIRun::Modules::Render;

void ModuleDescriptionLookup::addEssentialModules()
{
  addModuleDesc<ReadMatrixModule>("ReadMatrix", "DataIO", "SCIRun", "Functional, needs GUI and algorithm work.", "...");
  addModuleDesc<WriteMatrixModule>("WriteMatrix", "DataIO", "SCIRun", "Functional, outputs text files or binary .mat only.", "...");
  addModuleDesc<ReadFieldModule>("ReadField", "DataIO", "SCIRun", "Functional, needs GUI and algorithm work.", "...");
  addModuleDesc<WriteFieldModule>("WriteField", "DataIO", "SCIRun", "Functional, outputs binary .fld only.", "...");
  addModuleDesc<PrintDatatypeModule>("PrintDatatype", "String", "SCIRun", "...", "...");
  addModuleDesc<ReportMatrixInfoModule>("ReportMatrixInfo", "Math", "SCIRun", "Functional, needs GUI work.", "...");
  addModuleDesc<ReportFieldInfoModule>("ReportFieldInfo", "MiscField", "SCIRun", "Same as v4", "...");
  addModuleDesc<AppendMatrixModule>("AppendMatrix", "Math", "SCIRun", "Fully functional.", "...");
  addModuleDesc<EvaluateLinearAlgebraUnaryModule>("EvaluateLinearAlgebraUnary", "Math", "SCIRun", "Partially functional, needs GUI work.", "...");
  addModuleDesc<EvaluateLinearAlgebraBinaryModule>("EvaluateLinearAlgebraBinary", "Math", "SCIRun", "Partially functional, needs GUI work.", "...");
  addModuleDesc<CreateMatrixModule>("CreateMatrix", "Math", "SCIRun", "Functional, needs GUI work.", "...");
  addModuleDesc<SolveLinearSystemModule>("SolveLinearSystem", "Math", "SCIRun", "Four multi-threaded algorithms available.", "...");
  addModuleDesc<CreateStringModule>("CreateString", "String", "SCIRun", "Functional, needs GUI work.", "...");
	addModuleDesc<NetworkNotesModule>("NetworkNotes", "String", "SCIRun", "Functional, needs GUI work.", "...");
  //addModuleDesc<ShowStringModule>("ShowString", "String", "SCIRun", "...", "...");
  addModuleDesc<ShowFieldModule>("Some basic options available, still work in progress.", "...");
  addModuleDesc<CreateLatVol>("CreateLatVol", "NewField", "SCIRun", "Official ported v4 module.", "...");
  addModuleDesc<ViewScene>("Can display meshes and fields, pan/rotate/zoom.", "...");

  addModuleDesc<GetFieldBoundary>("GetFieldBoundary", "NewField", "SCIRun", "First real ported module", "...");
  addModuleDesc<CalculateSignedDistanceToField>("CalculateSignedDistanceToField", "ChangeFieldData", "SCIRun", "Second real ported module", "...");
  addModuleDesc<CalculateGradients>("CalculateGradients", "ChangeFieldData", "SCIRun", "Real ported module", "...");
  addModuleDesc<ConvertQuadSurfToTriSurf>("ConvertQuadSurfToTriSurf", "ChangeMesh", "SCIRun", "Real ported module", "...");
  addModuleDesc<AlignMeshBoundingBoxes>("AlignMeshBoundingBoxes", "ChangeMesh", "SCIRun", "Real ported module", "...");
  addModuleDesc<GetFieldNodes>("GetFieldNodes", "ChangeMesh", "SCIRun", "Real ported module", "...");
  addModuleDesc<SetFieldNodes>("SetFieldNodes", "ChangeMesh", "SCIRun", "Real ported module", "...");
  //addModuleDesc<TDCSSimulatorModule>("tDCSSimulator", "FiniteElements", "SCIRun", "Dummy module for design purposes", "...");
  addModuleDesc<SolveMinNormLeastSqSystem>("SolveMinNormLeastSqSystem", "Math", "SCIRun", "Real ported module", "...");
  addModuleDesc<CreateBasicColorMap>("CreateStandardColorMap", "Visualization", "SCIRun", "In progress: two color maps available", "...");
  addModuleDesc<GetDomainBoundary>("Real ported module: Many bugs and UI logic issues", "...");
  addModuleDesc<JoinFields>("Real ported module: Many bugs and UI logic issues", "...");
  addModuleDesc<CreateFieldData>("Real ported module", "...");
  addModuleDesc<CalculateFieldData>("Real ported module", "...");
  addModuleDesc<BuildFEMatrix>("BuildFEMatrix", "FiniteElements", "SCIRun", "In progress: main path through code works", "Generates stiffness matrix ");
  addModuleDesc<ResampleRegularMesh>("Real ported module", "...");
  addModuleDesc<FairMesh>("Real ported module", "...");
  //TODO: incomplete impl
  //addModuleDesc<ConvertFieldBasis>("NOT WORKING YET--Real ported module", "...");
  //addModuleDesc<ScaleFieldMeshAndData>("NOT WORKING YET--Real ported module", "...");
  addModuleDesc<ProjectPointsOntoMesh>("Real ported module", "...");
  addModuleDesc<CalculateDistanceToField>("Real ported module", "...");
  addModuleDesc<CalculateDistanceToFieldBoundary>("Real ported module", "...");
  addModuleDesc<MapFieldDataOntoNodes>("Real ported module", "...");
  addModuleDesc<MapFieldDataOntoElements>("Real ported module", "...");
  addModuleDesc<ClipFieldByFunction>("In progress", "...");
  addModuleDesc<MapFieldDataFromSourceToDestination>("Real ported module", "...");
  addModuleDesc<GetMatrixSlice>("New module based on GetRowOrColumnFromMatrix", "...");
  addModuleDesc<SetFieldDataToConstantValue>("Real ported module", "...");
  //addModuleDesc<ImportDatatypesFromMatlab>("Improved version of Matlab importer", "work in progress"); //not ready yet

  // insert module desc here
}

void ModuleDescriptionLookup::addBundleModules()
{
  //addModuleDesc<GetMatricesFromBundle>("Real ported module: improved UI", "...");
  //addModuleDesc<InsertMatricesIntoBundle>("Real ported module: improved UI", "...");
  //TODO: incomplete impl
  //addModuleDesc<GetFieldsFromBundle>("Real ported module: improved UI", "...");
  //addModuleDesc<InsertFieldsIntoBundle>("Real ported module: improved UI", "...");
  addModuleDesc<SplitFieldByDomain>("Real ported module", "...");
}

void ModuleDescriptionLookup::addTestingModules()
{
  addModuleDesc<SendScalarModule>("SendScalar", "Testing", "SCIRun", "Functional, needs GUI and algorithm work.", "...");
  addModuleDesc<ReceiveScalarModule>("ReceiveScalar", "Testing", "SCIRun", "...", "...");
  addModuleDesc<SendTestMatrixModule>("SendTestMatrix", "Testing", "SCIRun", "...", "...");
  addModuleDesc<ReceiveTestMatrixModule>("ReceiveTestMatrix", "Testing", "SCIRun", "...", "...");
  addModuleDesc<DynamicPortTester>("DynamicPortTester", "Testing", "SCIRun", "...", "...");
  addModuleDesc<AsyncPortTestModule>("...", "ViewScene clone");
  addModuleDesc<NeedToExecuteTester>("...", "...");
}
<|endoftext|>


<commit_before>#include <avr/pgmspace.h>

#include "state_scan.h"

#include "settings.h"
#include "internal_settings.h"
#include "eeprom_settings.h"
#include "receiver.h"
#include "channels.h"
#include "screens.h"

extern screens drawScreen;

static uint8_t orderedChanelIndex = 0;

namespace StateScan {
    void enter() {
        drawScreen.bandScanMode(STATE_SCAN);
    }

    void tick() {
        uint8_t channelName = pgm_read_byte(
            channelNames + Receiver::activeChannel
        );

        uint16_t channelFreq = pgm_read_byte(
            channelFreqTable + Receiver::activeChannel
        );

        drawScreen.updateBandScanMode(
            false,
            orderedChanelIndex,
            Receiver::rssiA,
            channelName,
            channelFreq,
            EepromSettings.rssiAMin,
            EepromSettings.rssiAMax);

        orderedChanelIndex = (orderedChanelIndex + 1) % CHANNEL_MAX_INDEX;
        uint8_t realChannelIndex = pgm_read_byte(
            channelFreqOrderedIndex + orderedChanelIndex
        );

        Receiver::setChannel(realChannelIndex);
    }
}
<commit_msg>Always start band scanner at lowest freq<commit_after>#include <avr/pgmspace.h>

#include "state_scan.h"

#include "settings.h"
#include "internal_settings.h"
#include "eeprom_settings.h"
#include "receiver.h"
#include "channels.h"
#include "screens.h"

extern screens drawScreen;

static uint8_t orderedChanelIndex = 0;

namespace StateScan {
    void enter() {
        orderedChanelIndex = 0;
        drawScreen.bandScanMode(STATE_SCAN);
    }

    void tick() {
        uint8_t channelName = pgm_read_byte(
            channelNames + Receiver::activeChannel
        );

        uint16_t channelFreq = pgm_read_byte(
            channelFreqTable + Receiver::activeChannel
        );

        drawScreen.updateBandScanMode(
            false,
            orderedChanelIndex,
            Receiver::rssiA,
            channelName,
            channelFreq,
            EepromSettings.rssiAMin,
            EepromSettings.rssiAMax);

        orderedChanelIndex = (orderedChanelIndex + 1) % CHANNEL_MAX_INDEX;
        uint8_t realChannelIndex = pgm_read_byte(
            channelFreqOrderedIndex + orderedChanelIndex
        );

        Receiver::setChannel(realChannelIndex);
    }
}
<|endoftext|>