<commit_before>#include <stdio.h>
#include <stdlib.h>

#include <string>
#include <iostream>
#include <utility>
#include <unordered_set>
#include <unordered_map>
using namespace std;

#include "scx/Dir.hpp"
#include "scx/FileInfo.hpp"
using namespace scx;

#include "Tools.h"
#include "ConsUnit.h"
#include "Parallel.h"

static const unordered_set<string> C_EXT = { "c" };
static const unordered_set<string> CXX_EXT = { "cc", "cxx", "cpp", "C" };
static const unordered_set<string> ASM_EXT = { "s", "S", "asm", "nas" };

static void Usage(const string& cmd)
{
    const string sp(cmd.size(), ' ');
    cout << ""
        "Usage:\n"
        "\t" + cmd + " [ file1 file1 | dir1 dir2 ]\n"
        "\t" + sp + " cc=?        C compiler.\n"
        "\t" + sp + " cxx=?       C++ compiler.\n"
        "\t" + sp + " flag=?      Compiler flag.\n"
        "\t" + sp + " ld=?        Linker.\n"
        "\t" + sp + " ldflag=?    Linker flag.\n"
        "\t" + sp + " ldfirst=?   First object file.\n"
        "\t" + sp + " as=?        Assembler.\n"
        "\t" + sp + " asflag=?    Assembler flag.\n"
        "\t" + sp + " jobs=?      Parallel build.\n"
        "\t" + sp + " workdir=?   Work direcotry.\n"
        "\t" + sp + " nlink       Do not link.\n"
        "\t" + sp + " verbose     Verbose output.\n"
        "\t" + sp + " clean       Clean build output.\n"
        "\t" + sp + " help        Show this help message.\n"
        "\n"
        "\t" + sp + " shared      Generate useShared library. (*)\n"
        "\t" + sp + " debug       Build with useDebug symbols. (*)\n"
        "\t" + sp + " c++11       Use clang & libc++. (*)\n"
        "\t" + sp + " thread      Link against pthread. (*)\n"
        "\n";

    cout << ""
        "Note:\n"
        "\t* Just for convenient. You may also use flags to approach the function.\n"
        "\n";

    cout << ""
        "Author:\n"
        "\tYanhui Shen <@diffcat on Twitter>\n";
}

int main(int argc, char** argv)
{
    unordered_map<string, string> ArgTable = {
        {   "out",      "b.out" },
        {   "cc",       "cc"    },
        {   "cxx",      "c++"   },
        {   "flag",     ""      },
        {   "ld",       "cc"    },
        {   "ldflag",   ""      },
        {   "ldfirst",  ""      },
        {   "as",       "as"    },
        {   "asflag",   ""      },
        {   "jobs",     "0"     },
        {   "workdir",  ""      }
    };

    bool clean = false;
    bool nlink = false;
    bool verbose = false;
    vector<string> allsrc;

    // Parse arguments.
    {
        bool useShared = false;
        bool useDebug = false;
        bool usePipe = true;
        bool useClangXX11 = false;
        bool useThread = false;

        for (int i = 1; i < argc; ++i) {
            const string& arg(argv[i]);

            // So obvisously, file name should not contain '='.
            size_t pos = arg.find('=');
            if (pos != string::npos && pos != arg.size()-1) {
                // Update key-value.
                auto iter = ArgTable.find(arg.substr(0, pos));
                if (iter != ArgTable.end()) {
                    iter->second = arg.substr(pos+1);
                } else {
                    cout << "Argument ignored!" << endl;
                    cout << "    Argument: " << arg << endl;
                }
            } else if (arg == "help") {
                Usage(argv[0]);
                return 0;
            } else if (arg == "verbose") {
                verbose = true;
            } else if (arg == "nlink") {
                nlink = true;
            } else if (arg == "clean") {
                clean = true;
            } else if (arg == "debug") {
                useDebug = true;
            } else if (arg == "shared") {
                useShared = true;
            } else if (arg == "c++11") {
                useClangXX11 = true;
            } else if (arg == "thread") {
                useThread = true;
            } else {
                // Add source files
                switch (FileInfo(arg).Type()) {
                case FileType::Directory:
                    {
                        const auto& files = Dir::ListDir(arg);
                        allsrc.reserve(allsrc.size() + files.size());
                        allsrc.insert(allsrc.end(), files.begin(), files.end());
                    }
                    break;

                case FileType::Regular:
                    {
                        allsrc.push_back(arg);
                    }
                    break;

                default:
                    {
                        cerr << "FATAL: bad argument: " << endl;
                        cerr << "arg: " << arg << endl;
                        return -1;
                    }
                    break;
                }
            }
        }

        if (!ArgTable["flag"].empty())
            ArgTable["flag"].insert(0, 1, ' ');

        if (!ArgTable["ldflag"].empty()) {
            ArgTable["ldflag"].insert(0, 1, ' ');
        }

        if (!ArgTable["workdir"].empty()) {
            auto& dir = ArgTable["workdir"];
            if (dir[dir.size()-1] != '/')
                dir += "/";
            const auto& info = FileInfo(dir);
            if (!info.Exists()) {
                if (!Dir::MakeDir(dir, 0744)) {
                    cerr << "Failed to create directory!" << endl;
                    cerr << "    Directory: " << dir << endl;
                    return -1;
                }
            } else if (info.Type() != FileType::Directory) {
                cerr << "Bad work directory! " << endl;
                cerr << "    Directory: " << dir << endl;
                cerr << "    File type: " << FileType::ToString(info.Type()) << endl;
                return -1;
            }
        }

        if (useDebug)
            ArgTable["flag"] += " -g";

        if (usePipe) {
            ArgTable["flag"] += " -pipe";
        }

        if (useShared) {
            ArgTable["flag"] += " -fPIC";
            ArgTable["ldflag"] += " -shared";
        }

        if (useThread) {
            ArgTable["ldflag"] += " -pthread";
        }

        if (useClangXX11) {
            ArgTable["cc"] = "clang";
            ArgTable["cxx"] = "clang++";
            ArgTable["flag"] += " -std=c++11 -stdlib=libc++";
            ArgTable["ldflag"] += " -stdlib=libc++";
        }

        // By default we'll take all files under current folder
        if (allsrc.empty())
            allsrc = Dir::ListDir(".");

        if (allsrc.empty()) {
            cerr << "FATAL: nothing to build!" << endl;
            return -1;
        }
    }

    // Prepare construct units.
    // Note: "workdir" & "out" should occur together
    bool hasCpp = false;
    bool hasOut = FileInfo(ArgTable["workdir"] + ArgTable["out"]).Exists();
    vector<ConsUnit> newUnits;
    string allObjects;

    for (const auto& file: allsrc) {
        ConsUnit unit(ArgTable["workdir"], file);
        string compiler;
        string compilerFlag;

        // Calculate dependence.
        bool ok = false;
        const string ext(FileInfo(file).Suffix());
        if (C_EXT.find(ext) != C_EXT.end()) {
            compiler = ArgTable["cc"];
            compilerFlag = ArgTable["flag"];
            ok = ConsUnit::InitC(unit, compiler, compilerFlag);
        } else if (CXX_EXT.find(ext) != CXX_EXT.end()) {
            hasCpp = true;
            compiler = ArgTable["cxx"];
            compilerFlag = ArgTable["flag"];
            ok = ConsUnit::InitCpp(unit, compiler, compilerFlag);
        } else if (ASM_EXT.find(ext) != ASM_EXT.end()) {
            compiler = ArgTable["as"];
            compilerFlag = ArgTable["asflag"];
            ok = ConsUnit::InitAsm(unit, compiler, compilerFlag);
        } else {
            continue;
        }

        if (ok) {
            if (unit.out == ArgTable["ldfirst"])
                allObjects = " " + unit.out + allObjects;
            else
                allObjects += " " + unit.out;
            if (!unit.cmd.empty())
                newUnits.push_back(std::move(unit));
        } else {
            cerr << "FATAL: failed to calculate dependence!" << endl;
            cerr << "    file:     " << file << endl;
            cerr << "    compiler: " << compiler << endl;
            cerr << "    flag:     " << ArgTable["flag"] << endl;
            return -1;
        }
    }

    if (hasCpp)
        ArgTable["ld"] = ArgTable["cxx"];

#ifdef DEBUG
    // Debug info.
    {
        auto fn = [](const vector<ConsUnit>& units)->void {
            for (const auto& unit: units) {
                cout << "in: " <<  unit.in << ", " << "out: " << unit.out << endl;
                cout << "\t" << unit.cmd << endl;
                cout << "\t";
                for (const auto& dep: unit.deps)
                    cout << dep << ", ";
                cout << endl;
            }
        };
        cout << "new units: " << endl;
        fn(newUnits);
    }
#endif

    // Let's build them all.
    if (!clean) {
        // compile
        if (!newUnits.empty()) {
            cout << "* Build: ";
            if (!verbose) {
                cout << newUnits.size() << (newUnits.size() > 1 ? " files" : " file");
            } else {
                for (size_t i = 0; i < newUnits.size(); ++i) {
                    cout << newUnits[i].in << ((i+1 < newUnits.size()) ? ", " : "");
                }
            }
            cout << endl;

            ParallelCompiler pc(newUnits);
            pc.SetVerbose(verbose);
            if (pc.Run(::stoi(ArgTable["jobs"])) != 0)
                return -1;
        }

        // link
        if ((!hasOut || !newUnits.empty()) && !nlink) {
            string ldCmd = ArgTable["ld"] + ArgTable["ldflag"];
            ldCmd += " -o " + ArgTable["workdir"] + ArgTable["out"] + allObjects;

            if (!verbose)
                cout << "- Link - " << ArgTable["workdir"] + ArgTable["out"] << endl;
            else
                cout << "- Link - " << ldCmd << endl;
            if (::system(ldCmd.c_str()) != 0) {
                cerr << "FATAL: failed to link!" << endl;
                cerr << "    file:   " << allObjects << endl;
                cerr << "    ld:     " << ArgTable["ld"] << endl;
                cerr << "    ldflag: " << ArgTable["ldflag"] << endl;
                return -2;
            }
        }
    } else {
        const string& cmd = "rm -f " + ArgTable["workdir"] + ArgTable["out"] + allObjects;
        cout << cmd << endl;
        ::system(cmd.c_str());
    }

    return 0;
}
<commit_msg>~ update help message<commit_after>#include <stdio.h>
#include <stdlib.h>

#include <string>
#include <iostream>
#include <utility>
#include <unordered_set>
#include <unordered_map>
using namespace std;

#include "scx/Dir.hpp"
#include "scx/FileInfo.hpp"
using namespace scx;

#include "Tools.h"
#include "ConsUnit.h"
#include "Parallel.h"

static const unordered_set<string> C_EXT = { "c" };
static const unordered_set<string> CXX_EXT = { "cc", "cxx", "cpp", "C" };
static const unordered_set<string> ASM_EXT = { "s", "S", "asm", "nas" };

static void Usage(const string& cmd)
{
    const string sp(cmd.size(), ' ');
    cout << ""
        "Usage:\n"
        "\t" + cmd + " [ file1 file1 | dir1 dir2 ]\n"
        "\t" + sp + " cc=?        C compiler.\n"
        "\t" + sp + " cxx=?       C++ compiler.\n"
        "\t" + sp + " flag=?      Compiler flag.\n"
        "\t" + sp + " ld=?        Linker.\n"
        "\t" + sp + " ldflag=?    Linker flag.\n"
        "\t" + sp + " ldfirst=?   First object file.\n"
        "\t" + sp + " as=?        Assembler.\n"
        "\t" + sp + " asflag=?    Assembler flag.\n"
        "\t" + sp + " jobs=?      Parallel build.\n"
        "\t" + sp + " workdir=?   Work direcotry.\n"
        "\t" + sp + " out=?       Binary output file name.\n"
        "\t" + sp + " nlink       Do not link.\n"
        "\t" + sp + " verbose     Verbose output.\n"
        "\t" + sp + " clean       Clean build output.\n"
        "\t" + sp + " help        Show this help message.\n"
        "\n"
        "\t" + sp + " shared      Generate useShared library. (*)\n"
        "\t" + sp + " debug       Build with useDebug symbols. (*)\n"
        "\t" + sp + " c++11       Use clang & libc++. (*)\n"
        "\t" + sp + " thread      Link against pthread. (*)\n"
        "\n";

    cout << ""
        "Note:\n"
        "\t* Just for convenient. You may also use flags to approach the function.\n"
        "\n";

    cout << ""
        "Author:\n"
        "\tYanhui Shen <@diffcat on Twitter>\n";
}

int main(int argc, char** argv)
{
    unordered_map<string, string> ArgTable = {
        {   "cc",       "cc"    },
        {   "cxx",      "c++"   },
        {   "flag",     ""      },
        {   "ld",       "cc"    },
        {   "ldflag",   ""      },
        {   "ldfirst",  ""      },
        {   "as",       "as"    },
        {   "asflag",   ""      },
        {   "jobs",     "0"     },
        {   "workdir",  ""      },
        {   "out",      "b.out" }
    };

    bool clean = false;
    bool nlink = false;
    bool verbose = false;
    vector<string> allsrc;

    // Parse arguments.
    {
        bool useShared = false;
        bool useDebug = false;
        bool usePipe = true;
        bool useClangXX11 = false;
        bool useThread = false;

        for (int i = 1; i < argc; ++i) {
            const string& arg(argv[i]);

            // So obvisously, file name should not contain '='.
            size_t pos = arg.find('=');
            if (pos != string::npos && pos != arg.size()-1) {
                // Update key-value.
                auto iter = ArgTable.find(arg.substr(0, pos));
                if (iter != ArgTable.end()) {
                    iter->second = arg.substr(pos+1);
                } else {
                    cout << "Argument ignored!" << endl;
                    cout << "    Argument: " << arg << endl;
                }
            } else if (arg == "help") {
                Usage(argv[0]);
                return 0;
            } else if (arg == "verbose") {
                verbose = true;
            } else if (arg == "nlink") {
                nlink = true;
            } else if (arg == "clean") {
                clean = true;
            } else if (arg == "debug") {
                useDebug = true;
            } else if (arg == "shared") {
                useShared = true;
            } else if (arg == "c++11") {
                useClangXX11 = true;
            } else if (arg == "thread") {
                useThread = true;
            } else {
                // Add source files
                switch (FileInfo(arg).Type()) {
                case FileType::Directory:
                    {
                        const auto& files = Dir::ListDir(arg);
                        allsrc.reserve(allsrc.size() + files.size());
                        allsrc.insert(allsrc.end(), files.begin(), files.end());
                    }
                    break;

                case FileType::Regular:
                    {
                        allsrc.push_back(arg);
                    }
                    break;

                default:
                    {
                        cerr << "FATAL: bad argument: " << endl;
                        cerr << "arg: " << arg << endl;
                        return -1;
                    }
                    break;
                }
            }
        }

        if (!ArgTable["flag"].empty())
            ArgTable["flag"].insert(0, 1, ' ');

        if (!ArgTable["ldflag"].empty()) {
            ArgTable["ldflag"].insert(0, 1, ' ');
        }

        if (!ArgTable["workdir"].empty()) {
            auto& dir = ArgTable["workdir"];
            if (dir[dir.size()-1] != '/')
                dir += "/";
            const auto& info = FileInfo(dir);
            if (!info.Exists()) {
                if (!Dir::MakeDir(dir, 0744)) {
                    cerr << "Failed to create directory!" << endl;
                    cerr << "    Directory: " << dir << endl;
                    return -1;
                }
            } else if (info.Type() != FileType::Directory) {
                cerr << "Bad work directory! " << endl;
                cerr << "    Directory: " << dir << endl;
                cerr << "    File type: " << FileType::ToString(info.Type()) << endl;
                return -1;
            }
        }

        if (useDebug)
            ArgTable["flag"] += " -g";

        if (usePipe) {
            ArgTable["flag"] += " -pipe";
        }

        if (useShared) {
            ArgTable["flag"] += " -fPIC";
            ArgTable["ldflag"] += " -shared";
        }

        if (useThread) {
            ArgTable["ldflag"] += " -pthread";
        }

        if (useClangXX11) {
            ArgTable["cc"] = "clang";
            ArgTable["cxx"] = "clang++";
            ArgTable["flag"] += " -std=c++11 -stdlib=libc++";
            ArgTable["ldflag"] += " -stdlib=libc++";
        }

        // By default we'll take all files under current folder
        if (allsrc.empty())
            allsrc = Dir::ListDir(".");

        if (allsrc.empty()) {
            cerr << "FATAL: nothing to build!" << endl;
            return -1;
        }
    }

    // Prepare construct units.
    // Note: "workdir" & "out" should occur together
    bool hasCpp = false;
    bool hasOut = FileInfo(ArgTable["workdir"] + ArgTable["out"]).Exists();
    vector<ConsUnit> newUnits;
    string allObjects;

    for (const auto& file: allsrc) {
        ConsUnit unit(ArgTable["workdir"], file);
        string compiler;
        string compilerFlag;

        // Calculate dependence.
        bool ok = false;
        const string ext(FileInfo(file).Suffix());
        if (C_EXT.find(ext) != C_EXT.end()) {
            compiler = ArgTable["cc"];
            compilerFlag = ArgTable["flag"];
            ok = ConsUnit::InitC(unit, compiler, compilerFlag);
        } else if (CXX_EXT.find(ext) != CXX_EXT.end()) {
            hasCpp = true;
            compiler = ArgTable["cxx"];
            compilerFlag = ArgTable["flag"];
            ok = ConsUnit::InitCpp(unit, compiler, compilerFlag);
        } else if (ASM_EXT.find(ext) != ASM_EXT.end()) {
            compiler = ArgTable["as"];
            compilerFlag = ArgTable["asflag"];
            ok = ConsUnit::InitAsm(unit, compiler, compilerFlag);
        } else {
            continue;
        }

        if (ok) {
            if (unit.out == ArgTable["ldfirst"])
                allObjects = " " + unit.out + allObjects;
            else
                allObjects += " " + unit.out;
            if (!unit.cmd.empty())
                newUnits.push_back(std::move(unit));
        } else {
            cerr << "FATAL: failed to calculate dependence!" << endl;
            cerr << "    file:     " << file << endl;
            cerr << "    compiler: " << compiler << endl;
            cerr << "    flag:     " << ArgTable["flag"] << endl;
            return -1;
        }
    }

    if (hasCpp)
        ArgTable["ld"] = ArgTable["cxx"];

#ifdef DEBUG
    // Debug info.
    {
        auto fn = [](const vector<ConsUnit>& units)->void {
            for (const auto& unit: units) {
                cout << "in: " <<  unit.in << ", " << "out: " << unit.out << endl;
                cout << "\t" << unit.cmd << endl;
                cout << "\t";
                for (const auto& dep: unit.deps)
                    cout << dep << ", ";
                cout << endl;
            }
        };
        cout << "new units: " << endl;
        fn(newUnits);
    }
#endif

    // Let's build them all.
    if (!clean) {
        // compile
        if (!newUnits.empty()) {
            cout << "* Build: ";
            if (!verbose) {
                cout << newUnits.size() << (newUnits.size() > 1 ? " files" : " file");
            } else {
                for (size_t i = 0; i < newUnits.size(); ++i) {
                    cout << newUnits[i].in << ((i+1 < newUnits.size()) ? ", " : "");
                }
            }
            cout << endl;

            ParallelCompiler pc(newUnits);
            pc.SetVerbose(verbose);
            if (pc.Run(::stoi(ArgTable["jobs"])) != 0)
                return -1;
        }

        // link
        if ((!hasOut || !newUnits.empty()) && !nlink) {
            string ldCmd = ArgTable["ld"] + ArgTable["ldflag"];
            ldCmd += " -o " + ArgTable["workdir"] + ArgTable["out"] + allObjects;

            if (!verbose)
                cout << "- Link - " << ArgTable["workdir"] + ArgTable["out"] << endl;
            else
                cout << "- Link - " << ldCmd << endl;
            if (::system(ldCmd.c_str()) != 0) {
                cerr << "FATAL: failed to link!" << endl;
                cerr << "    file:   " << allObjects << endl;
                cerr << "    ld:     " << ArgTable["ld"] << endl;
                cerr << "    ldflag: " << ArgTable["ldflag"] << endl;
                return -2;
            }
        }
    } else {
        const string& cmd = "rm -f " + ArgTable["workdir"] + ArgTable["out"] + allObjects;
        cout << cmd << endl;
        ::system(cmd.c_str());
    }

    return 0;
}
<|endoftext|>


<commit_before>#include <sstream>
#include <iostream>
#include <core/global.hpp>

#include "HElib/FHE.h"
#include "core/core.hpp"
#include "core/file_util.hpp"
#include "core/protocol.hpp"
namespace core {
bool genKeypair(Protocol protocol, const std::string &metaFilePath) {
    std::string dirPath = util::getDirPath(metaFilePath);
    std::fstream skStream(util::concatenate(dirPath, "fhe_key.sk"),
                          std::ios::binary | std::ios::out);
    std::fstream ctxtStream(util::concatenate(dirPath, "fhe_key.ctxt"),
                            std::ios::binary | std::ios::out);
    std::fstream pkStream(util::concatenate(dirPath, "fhe_key.pk"),
                          std::ios::binary | std::ios::out);
    if (!skStream.is_open() || !ctxtStream.is_open() || !pkStream.is_open())
        return false;
    bool ok = protocol::genKeypair(protocol, skStream, ctxtStream, pkStream);
    skStream.close();
    ctxtStream.close();
    pkStream.close();
    return ok;
}

context_ptr loadContext(bool *ok, const std::string &contextFile) {
    std::fstream in(contextFile, std::ios::binary | std::ios::in);
    if (!in.is_open()) {
        if (ok) *ok = false;
        return nullptr;
    }

    FHEArg args;
    in >> args;
    auto context = std::make_shared<FHEcontext>(args.m, args.p, args.r);
    if (context == nullptr) {
        if (ok) *ok = false;
        return nullptr;
    }
    buildModChain(*context, args.L);
    return context;
}

pk_ptr loadPK(bool *ok, const context_ptr &context, const std::string &pkFile) {
    std::fstream in(pkFile, std::ios::binary | std::ios::in);
    if (!in.is_open()) {
        if (ok) *ok = false;
        return nullptr;
    }

    auto pk = std::make_shared<FHEPubKey>(*context);
    if (pk == nullptr) {
        if (ok) *ok = false;
        return nullptr;
    }

    in >> *pk;
    in.close();

    if (ok) *ok = true;
    return pk;
}

sk_ptr loadSK(bool *ok, const context_ptr &context, const std::string &skFile) {
    if (context == nullptr) {
        if (!ok) *ok = false;
        return nullptr;
    }

    std::fstream in(skFile, std::ios::binary | std::ios::in);
    if (!in.is_open()) {
        L_WARN(global::_console, "Can not open {0}", skFile);
        if (!ok) *ok = false;
        return nullptr;
    }

    auto sk = std::make_shared<FHESecKey>(*context);
    if (sk == nullptr) {
        if (!ok) *ok = false;
        return nullptr;
    }

    in >> *sk;
    in.close();
    if (!ok) *ok = true;
    return sk;
}

static bool loadFromMetaFile(const std::string &metaFilePath,
                             core::context_ptr &context,
                             core::pk_ptr &pk,
                             util::Meta &meta) {
    bool ok;
    std::tie(meta, ok) = util::readMetaFile(metaFilePath);

    if (!ok) {
        L_ERROR(global::_console, "Can not find meta file {0}", metaFilePath);
        return false;
    }

    if (meta.find("protocol") == meta.end() || meta["protocol"].empty()) {
        L_ERROR(global::_console, "No protocol was set in {0}", metaFilePath);
        return false;
    }

    auto dirPath = util::getDirPath(metaFilePath);
    auto contextPath = util::concatenate(dirPath, "fhe_key.ctxt");
    context = loadContext(&ok, contextPath);
    if (!ok) {
        L_ERROR(global::_console, "Can not load fhe_key.ctxt in {0}", dirPath);
        return false;
    }

    auto pkPath = util::concatenate(dirPath, "fhe_key.pk");
    pk = loadPK(&ok, context, pkPath);
    if (!ok) {
        context = nullptr;
        L_ERROR(global::_console, "Can not load fhe_key.pk in {0}", dirPath);
        return false;
    }

    return true;
}

static bool loadFromMetaFile(const std::string &metaFilePath,
                             core::context_ptr &context,
                             core::pk_ptr &pk,
                             core::sk_ptr &sk,
                             util::Meta &meta) {
    if (!loadFromMetaFile(metaFilePath, context, pk, meta))
        return false;

    auto dirPath = util::getDirPath(metaFilePath);
    auto skPath = util::concatenate(dirPath, "fhe_key.sk");
    bool ok;
    sk = loadSK(&ok, context, skPath);
    if (!ok) {
        L_ERROR(global::_console, "Can not load fhe_key.sk in {0}", dirPath);
        return false;
    }

    return true;
}

bool encrypt(const std::string &inputFilePath,
             const std::string &outputFilePath,
             const std::string &metaFilePath) {
    util::Meta meta;
    core::context_ptr context = nullptr;
    core::pk_ptr pk = nullptr;
    if(!loadFromMetaFile(metaFilePath, context, pk, meta))
        return false;

    auto protocol = core::getProtocol(meta["protocol"].front());
    switch (protocol) {
    case core::Protocol::PROT_CI2:
        return protocol::chi2::encrypt(inputFilePath, outputFilePath, pk);
    case core::Protocol::PROT_CON:
        return protocol::contingency::encrypt(inputFilePath, outputFilePath, pk);
    default:
        L_ERROR(global::_console, "Unkonwn protocol was set in {0}", metaFilePath);
        return false;
    }
}

bool decrypt(const std::string &inputFilePath,
             const std::string &outputFilePath,
             const std::string &metaFilePath) {
    util::Meta meta;
    core::context_ptr context = nullptr;
    core::pk_ptr pk = nullptr;
    core::sk_ptr sk = nullptr;
    if (!loadFromMetaFile(metaFilePath, context, pk, sk, meta))
        return false;
    auto protocol = getProtocol(meta["protocol"].front());
    switch (protocol) {
    case core::Protocol::PROT_CI2:
        return protocol::chi2::decrypt(inputFilePath, outputFilePath, pk, sk);
    case core::Protocol::PROT_CON:
        return protocol::contingency::decrypt(inputFilePath, outputFilePath, pk, sk);
    default:
        L_ERROR(global::_console, "Unkonwn protocol was set in {0}", metaFilePath);
        return false;
    }
}

bool loadCiphers(std::vector<Ctxt> &out, const pk_ptr &pk, const std::string &file) {
    std::ifstream in(file);
    if (!in.is_open()) {
        L_ERROR(global::_console, "Can not open file {0}", file);
        return false;
    }

    Ctxt cipher(*pk);
    while (!in.eof() && in.peek() != -1) {
        in >> cipher;
        out.push_back(cipher);
    }
    in.close();
    return true;
}

bool loadCiphers(std::list<Ctxt> &out, const pk_ptr &pk, const std::string &file) {
    std::ifstream in(file);
    if (!in.is_open()) {
        L_ERROR(global::_console, "Can not open file {0}", file);
        return false;
    }

    Ctxt cipher(*pk);
    while (!in.eof() && in.peek() != -1) {
        in >> cipher;
        out.push_back(cipher);
    }
    in.close();
    return true;
}

bool dumpCiphers(const std::list<Ctxt> &ciphers, const std::string &file) {
    std::ofstream out(file);
    if (!out.is_open()) {
        L_ERROR(global::_console, "Can not dump into file {0}", file);
        return false;
    }

    for (auto &c : ciphers) {
        out << c;
    }
    out.close();
    return true;
}

bool evaluate(const std::string &sessionDirPath,
              const std::string &outputDirPath,
              const std::string &metaFilePath) {
    auto dirs = util::listDir(sessionDirPath, util::flag_t::DIR_ONLY);
    std::vector<std::string> userDirs;
    for (auto dir : dirs) {
        if (dir.compare(".") == 0 || dir.compare("..") == 0)
            continue;
        if (dir.compare("Meta") == 0 || dir.compare("result") == 0)
            continue;
        userDirs.push_back(util::concatenate(sessionDirPath, dir));
    }

    util::Meta meta;
    core::context_ptr context;
    core::pk_ptr pk;
    if (!loadFromMetaFile(metaFilePath, context, pk, meta))
        return false;

    auto protocol = core::getProtocol(meta["protocol"].front());
    switch (protocol) {
    case core::Protocol::PROT_CI2:
        return protocol::chi2::evaluate(userDirs, outputDirPath, pk);
    case core::Protocol::PROT_CON:
        return protocol::contingency::evaluate(userDirs, outputDirPath, pk);
    default:
        L_ERROR(global::_console, "Unkonwn protocol was set in {0}", metaFilePath);
        return false;
    }
}
} // nammespae core
<commit_msg>fix bug in loadSK<commit_after>#include <sstream>
#include <iostream>
#include <core/global.hpp>

#include "HElib/FHE.h"
#include "core/core.hpp"
#include "core/file_util.hpp"
#include "core/protocol.hpp"
namespace core {
bool genKeypair(Protocol protocol, const std::string &metaFilePath) {
    std::string dirPath = util::getDirPath(metaFilePath);
    std::fstream skStream(util::concatenate(dirPath, "fhe_key.sk"),
                          std::ios::binary | std::ios::out);
    std::fstream ctxtStream(util::concatenate(dirPath, "fhe_key.ctxt"),
                            std::ios::binary | std::ios::out);
    std::fstream pkStream(util::concatenate(dirPath, "fhe_key.pk"),
                          std::ios::binary | std::ios::out);
    if (!skStream.is_open() || !ctxtStream.is_open() || !pkStream.is_open())
        return false;
    bool ok = protocol::genKeypair(protocol, skStream, ctxtStream, pkStream);
    skStream.close();
    ctxtStream.close();
    pkStream.close();
    return ok;
}

context_ptr loadContext(bool *ok, const std::string &contextFile) {
    std::fstream in(contextFile, std::ios::binary | std::ios::in);
    if (!in.is_open()) {
        if (ok) *ok = false;
        return nullptr;
    }

    FHEArg args;
    in >> args;
    auto context = std::make_shared<FHEcontext>(args.m, args.p, args.r);
    if (context == nullptr) {
        if (ok) *ok = false;
        return nullptr;
    }
    buildModChain(*context, args.L);
    return context;
}

pk_ptr loadPK(bool *ok, const context_ptr &context, const std::string &pkFile) {
    std::fstream in(pkFile, std::ios::binary | std::ios::in);
    if (!in.is_open()) {
        if (ok) *ok = false;
        return nullptr;
    }

    auto pk = std::make_shared<FHEPubKey>(*context);
    if (pk == nullptr) {
        if (ok) *ok = false;
        return nullptr;
    }

    in >> *pk;
    in.close();

    if (ok) *ok = true;
    return pk;
}

sk_ptr loadSK(bool *ok, const context_ptr &context, const std::string &skFile) {
    if (context == nullptr) {
        if (ok) *ok = false;
        return nullptr;
    }

    std::fstream in(skFile, std::ios::binary | std::ios::in);
    if (!in.is_open()) {
        L_WARN(global::_console, "Can not open {0}", skFile);
        if (ok) *ok = false;
        return nullptr;
    }

    auto sk = std::make_shared<FHESecKey>(*context);
    if (sk == nullptr) {
        if (ok) *ok = false;
        return nullptr;
    }

    in >> *sk;
    in.close();
    if (ok) *ok = true;
    return sk;
}

static bool loadFromMetaFile(const std::string &metaFilePath,
                             core::context_ptr &context,
                             core::pk_ptr &pk,
                             util::Meta &meta) {
    bool ok;
    std::tie(meta, ok) = util::readMetaFile(metaFilePath);

    if (!ok) {
        L_ERROR(global::_console, "Can not find meta file {0}", metaFilePath);
        return false;
    }

    if (meta.find("protocol") == meta.end() || meta["protocol"].empty()) {
        L_ERROR(global::_console, "No protocol was set in {0}", metaFilePath);
        return false;
    }

    auto dirPath = util::getDirPath(metaFilePath);
    auto contextPath = util::concatenate(dirPath, "fhe_key.ctxt");
    context = loadContext(&ok, contextPath);
    if (!ok) {
        L_ERROR(global::_console, "Can not load fhe_key.ctxt in {0}", dirPath);
        return false;
    }

    auto pkPath = util::concatenate(dirPath, "fhe_key.pk");
    pk = loadPK(&ok, context, pkPath);
    if (!ok) {
        context = nullptr;
        L_ERROR(global::_console, "Can not load fhe_key.pk in {0}", dirPath);
        return false;
    }

    return true;
}

static bool loadFromMetaFile(const std::string &metaFilePath,
                             core::context_ptr &context,
                             core::pk_ptr &pk,
                             core::sk_ptr &sk,
                             util::Meta &meta) {
    if (!loadFromMetaFile(metaFilePath, context, pk, meta))
        return false;

    auto dirPath = util::getDirPath(metaFilePath);
    auto skPath = util::concatenate(dirPath, "fhe_key.sk");
    bool ok;
    sk = loadSK(&ok, context, skPath);
    if (!ok) {
        L_ERROR(global::_console, "Can not load fhe_key.sk in {0}", dirPath);
        return false;
    }

    return true;
}

bool encrypt(const std::string &inputFilePath,
             const std::string &outputFilePath,
             const std::string &metaFilePath) {
    util::Meta meta;
    core::context_ptr context = nullptr;
    core::pk_ptr pk = nullptr;
    if(!loadFromMetaFile(metaFilePath, context, pk, meta))
        return false;

    auto protocol = core::getProtocol(meta["protocol"].front());
    switch (protocol) {
    case core::Protocol::PROT_CI2:
        return protocol::chi2::encrypt(inputFilePath, outputFilePath, pk);
    case core::Protocol::PROT_CON:
        return protocol::contingency::encrypt(inputFilePath, outputFilePath, pk);
    default:
        L_ERROR(global::_console, "Unkonwn protocol was set in {0}", metaFilePath);
        return false;
    }
}

bool decrypt(const std::string &inputFilePath,
             const std::string &outputFilePath,
             const std::string &metaFilePath) {
    util::Meta meta;
    core::context_ptr context = nullptr;
    core::pk_ptr pk = nullptr;
    core::sk_ptr sk = nullptr;
    if (!loadFromMetaFile(metaFilePath, context, pk, sk, meta))
        return false;
    auto protocol = getProtocol(meta["protocol"].front());
    switch (protocol) {
    case core::Protocol::PROT_CI2:
        return protocol::chi2::decrypt(inputFilePath, outputFilePath, pk, sk);
    case core::Protocol::PROT_CON:
        return protocol::contingency::decrypt(inputFilePath, outputFilePath, pk, sk);
    default:
        L_ERROR(global::_console, "Unkonwn protocol was set in {0}", metaFilePath);
        return false;
    }
}

bool loadCiphers(std::vector<Ctxt> &out, const pk_ptr &pk, const std::string &file) {
    std::ifstream in(file);
    if (!in.is_open()) {
        L_ERROR(global::_console, "Can not open file {0}", file);
        return false;
    }

    Ctxt cipher(*pk);
    while (!in.eof() && in.peek() != -1) {
        in >> cipher;
        out.push_back(cipher);
    }
    in.close();
    return true;
}

bool loadCiphers(std::list<Ctxt> &out, const pk_ptr &pk, const std::string &file) {
    std::ifstream in(file);
    if (!in.is_open()) {
        L_ERROR(global::_console, "Can not open file {0}", file);
        return false;
    }

    Ctxt cipher(*pk);
    while (!in.eof() && in.peek() != -1) {
        in >> cipher;
        out.push_back(cipher);
    }
    in.close();
    return true;
}

bool dumpCiphers(const std::list<Ctxt> &ciphers, const std::string &file) {
    std::ofstream out(file);
    if (!out.is_open()) {
        L_ERROR(global::_console, "Can not dump into file {0}", file);
        return false;
    }

    for (auto &c : ciphers) {
        out << c;
    }
    out.close();
    return true;
}

bool evaluate(const std::string &sessionDirPath,
              const std::string &outputDirPath,
              const std::string &metaFilePath) {
    auto dirs = util::listDir(sessionDirPath, util::flag_t::DIR_ONLY);
    std::vector<std::string> userDirs;
    for (auto dir : dirs) {
        if (dir.compare(".") == 0 || dir.compare("..") == 0)
            continue;
        if (dir.compare("Meta") == 0 || dir.compare("result") == 0)
            continue;
        userDirs.push_back(util::concatenate(sessionDirPath, dir));
    }

    util::Meta meta;
    core::context_ptr context;
    core::pk_ptr pk;
    if (!loadFromMetaFile(metaFilePath, context, pk, meta))
        return false;

    auto protocol = core::getProtocol(meta["protocol"].front());
    switch (protocol) {
    case core::Protocol::PROT_CI2:
        return protocol::chi2::evaluate(userDirs, outputDirPath, pk);
    case core::Protocol::PROT_CON:
        return protocol::contingency::evaluate(userDirs, outputDirPath, pk);
    default:
        L_ERROR(global::_console, "Unkonwn protocol was set in {0}", metaFilePath);
        return false;
    }
}
} // nammespae core
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Cloudius Systems
 */

#include "database.hh"
#include "core/app-template.hh"
#include "core/distributed.hh"
#include "thrift/server.hh"
#include "transport/server.hh"
#include "http/httpd.hh"
#include "api/api.hh"
#include "db/config.hh"
#include "message/messaging_service.hh"
#include "gms/failure_detector.hh"
#include "gms/gossiper.hh"

namespace bpo = boost::program_options;

static future<>
read_config(bpo::variables_map& opts, db::config& cfg) {
    if (opts.count("options-file") == 0) {
        return make_ready_future<>();
    }
    return cfg.read_from_file(opts["options-file"].as<sstring>());
}

future<> init_messaging_service(auto listen_address, auto seed_provider) {
    const gms::inet_address listen(listen_address);
    std::set<gms::inet_address> seeds;
    for (auto& x : seed_provider.parameters) {
        seeds.emplace(x.first);
    }
    return net::get_messaging_service().start(listen).then([seeds] {
        auto& ms = net::get_local_messaging_service();
        print("Messaging server listening on ip %s port %d ...\n", ms.listen_address(), ms.port());
        return gms::get_failure_detector().start_single().then([seeds] {
            return gms::get_gossiper().start_single().then([seeds] {
                auto& gossiper = gms::get_local_gossiper();
                gossiper.set_seeds(seeds);
                using namespace std::chrono;
                auto now = high_resolution_clock::now().time_since_epoch();
                int generation_number = duration_cast<seconds>(now).count();
                return gossiper.start(generation_number).then([] {
                    print("Start gossiper service ...\n");
                });
            });
        });
    });
}

int main(int ac, char** av) {
    app_template app;
    auto opt_add = app.add_options();

    auto cfg = make_lw_shared<db::config>();
    cfg->add_options(opt_add)
        ("api-port", bpo::value<uint16_t>()->default_value(10000), "Http Rest API port")
        // TODO : default, always read?
        ("options-file", bpo::value<sstring>(), "cassandra.yaml file to read options from")
        ;

    auto server = std::make_unique<distributed<thrift_server>>();
    distributed<database> db;
    distributed<cql3::query_processor> qp;
    service::storage_proxy proxy{db};
    api::http_context ctx(db);

    return app.run(ac, av, [&] {
        auto&& opts = app.configuration();
        uint16_t thrift_port = cfg->rpc_port();
        uint16_t cql_port = cfg->native_transport_port();
        uint16_t api_port = opts["api-port"].as<uint16_t>();
        sstring listen_address = cfg->listen_address();
        auto seed_provider= cfg->seed_provider();

        return read_config(opts, *cfg).then([cfg, &db]() {
            return db.start(std::move(*cfg));
        }).then([&db] {
            engine().at_exit([&db] { return db.stop(); });
            return db.invoke_on_all(&database::init_from_data_directory);
        }).then([listen_address, seed_provider] {
            return init_messaging_service(listen_address, seed_provider);
        }).then([&db, &proxy, &qp] {
            return qp.start(std::ref(proxy), std::ref(db)).then([&qp] {
                engine().at_exit([&qp] { return qp.stop(); });
            });
        }).then([&db, &proxy, &qp, cql_port, thrift_port] {
            auto cserver = new distributed<cql_server>;
            cserver->start(std::ref(proxy), std::ref(qp)).then([server = std::move(cserver), cql_port] () mutable {
                server->invoke_on_all(&cql_server::listen, ipv4_addr{cql_port});
            }).then([cql_port] {
                std::cout << "CQL server listening on port " << cql_port << " ...\n";
            });
            auto tserver = new distributed<thrift_server>;
            tserver->start(std::ref(db)).then([server = std::move(tserver), thrift_port] () mutable {
                server->invoke_on_all(&thrift_server::listen, ipv4_addr{thrift_port});
            }).then([thrift_port] {
                std::cout << "Thrift server listening on port " << thrift_port << " ...\n";
            });
        }).then([&db, api_port, &ctx]{
            ctx.http_server.start().then([api_port, &ctx] {
                return set_server(ctx);
            }).then([&ctx, api_port] {
                ctx.http_server.listen(api_port);
            }).then([api_port] {
                std::cout << "Seastar HTTP server listening on port " << api_port << " ...\n";
            });
        }).or_terminate();
    });
}
<commit_msg>main: use rpc-address config option for cql and thrift<commit_after>/*
 * Copyright 2014 Cloudius Systems
 */

#include "database.hh"
#include "core/app-template.hh"
#include "core/distributed.hh"
#include "thrift/server.hh"
#include "transport/server.hh"
#include "http/httpd.hh"
#include "api/api.hh"
#include "db/config.hh"
#include "message/messaging_service.hh"
#include "gms/failure_detector.hh"
#include "gms/gossiper.hh"
#include "dns.hh"

namespace bpo = boost::program_options;

static future<>
read_config(bpo::variables_map& opts, db::config& cfg) {
    if (opts.count("options-file") == 0) {
        return make_ready_future<>();
    }
    return cfg.read_from_file(opts["options-file"].as<sstring>());
}

future<> init_messaging_service(auto listen_address, auto seed_provider) {
    const gms::inet_address listen(listen_address);
    std::set<gms::inet_address> seeds;
    for (auto& x : seed_provider.parameters) {
        seeds.emplace(x.first);
    }
    return net::get_messaging_service().start(listen).then([seeds] {
        auto& ms = net::get_local_messaging_service();
        print("Messaging server listening on ip %s port %d ...\n", ms.listen_address(), ms.port());
        return gms::get_failure_detector().start_single().then([seeds] {
            return gms::get_gossiper().start_single().then([seeds] {
                auto& gossiper = gms::get_local_gossiper();
                gossiper.set_seeds(seeds);
                using namespace std::chrono;
                auto now = high_resolution_clock::now().time_since_epoch();
                int generation_number = duration_cast<seconds>(now).count();
                return gossiper.start(generation_number).then([] {
                    print("Start gossiper service ...\n");
                });
            });
        });
    });
}

int main(int ac, char** av) {
    app_template app;
    auto opt_add = app.add_options();

    auto cfg = make_lw_shared<db::config>();
    cfg->add_options(opt_add)
        ("api-port", bpo::value<uint16_t>()->default_value(10000), "Http Rest API port")
        // TODO : default, always read?
        ("options-file", bpo::value<sstring>(), "cassandra.yaml file to read options from")
        ;

    auto server = std::make_unique<distributed<thrift_server>>();
    distributed<database> db;
    distributed<cql3::query_processor> qp;
    service::storage_proxy proxy{db};
    api::http_context ctx(db);

    return app.run(ac, av, [&] {
        auto&& opts = app.configuration();
        uint16_t thrift_port = cfg->rpc_port();
        uint16_t cql_port = cfg->native_transport_port();
        uint16_t api_port = opts["api-port"].as<uint16_t>();
        sstring listen_address = cfg->listen_address();
        sstring rpc_address = cfg->rpc_address();
        auto seed_provider= cfg->seed_provider();

        return read_config(opts, *cfg).then([cfg, &db]() {
            return db.start(std::move(*cfg));
        }).then([&db] {
            engine().at_exit([&db] { return db.stop(); });
            return db.invoke_on_all(&database::init_from_data_directory);
        }).then([listen_address, seed_provider] {
            return init_messaging_service(listen_address, seed_provider);
        }).then([&db, &proxy, &qp] {
            return qp.start(std::ref(proxy), std::ref(db)).then([&qp] {
                engine().at_exit([&qp] { return qp.stop(); });
            });
        }).then([rpc_address] {
            return dns::gethostbyname(rpc_address);
        }).then([&db, &proxy, &qp, cql_port, thrift_port] (dns::hostent e) {
            auto rpc_address = e.addresses[0].in.s_addr;
            auto cserver = new distributed<cql_server>;
            cserver->start(std::ref(proxy), std::ref(qp)).then([server = std::move(cserver), cql_port, rpc_address] () mutable {
                server->invoke_on_all(&cql_server::listen, ipv4_addr{rpc_address, cql_port});
            }).then([cql_port] {
                std::cout << "CQL server listening on port " << cql_port << " ...\n";
            });
            auto tserver = new distributed<thrift_server>;
            tserver->start(std::ref(db)).then([server = std::move(tserver), thrift_port, rpc_address] () mutable {
                server->invoke_on_all(&thrift_server::listen, ipv4_addr{rpc_address, thrift_port});
            }).then([thrift_port] {
                std::cout << "Thrift server listening on port " << thrift_port << " ...\n";
            });
        }).then([&db, api_port, &ctx]{
            ctx.http_server.start().then([api_port, &ctx] {
                return set_server(ctx);
            }).then([&ctx, api_port] {
                ctx.http_server.listen(api_port);
            }).then([api_port] {
                std::cout << "Seastar HTTP server listening on port " << api_port << " ...\n";
            });
        }).or_terminate();
    });
}
<|endoftext|>


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

 This file is part of the GLC-lib library.
 Copyright (C) 2005 Laurent Ribon (laumaya@users.sourceforge.net)
 Version 0.9, packaged on Novemeber, 2005.

 http://glc-lib.sourceforge.net

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

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

 You should have received a copy of the GNU General Public License
 along with GLC-lib; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

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

//! \file glc_face.cpp implementation of the GLC_Face class.

#include <QtDebug>
#include "glc_face.h"

//////////////////////////////////////////////////////////////////////
// Constructor Destructor
//////////////////////////////////////////////////////////////////////

// Construct an empty Face
GLC_Face::GLC_Face()
:m_NbrVertex(0)
{

}

// Copy constructor
GLC_Face::GLC_Face(const GLC_Face *pFaceToCopy)
:m_NbrVertex(0)
{
	GLC_Vertex *pVertex;
	for (int i= 0; i < pFaceToCopy->GetNombre(); i++)
	{
		pVertex= new GLC_Vertex(pFaceToCopy->m_Array_pVertex[i]);
		AddVertex(pVertex);
	}
}

// Delete Face's Vertexs (GLC_Vertex)
GLC_Face::~GLC_Face(void)
{

	for (int i= m_NbrVertex - 1; i >= 0; i--)
	{
		delete m_Array_pVertex[i];
	}
}
/////////////////////////////////////////////////////////////////////
// Set Functions
//////////////////////////////////////////////////////////////////////

// Add a vertex to the face
void GLC_Face::AddVertex(GLC_Vertex* pVertex)
{
	m_Array_pVertex[m_NbrVertex]= pVertex;
	m_NbrVertex++;
}

// Add an array of vertex to the face
void GLC_Face::AddVertexs(GLC_Vertex** pVertex, int Nbr)
{
	//! \todo Check vertexs number
	for (int i= 0; i < Nbr; i++)
	{
		m_Array_pVertex[m_NbrVertex + i]= pVertex[i];
	}
	m_NbrVertex+= Nbr;
}

//////////////////////////////////////////////////////////////////////
// OpenGL Functions
//////////////////////////////////////////////////////////////////////
// Face SetUp
void GLC_Face::GlDraw(void)
{
	glBegin(GL_POLYGON);
		for (int i= 0; i < m_NbrVertex; i++)
		{
			m_Array_pVertex[i]->GlDraw();
		}
	glEnd();

}
<commit_msg>Rename some members.<commit_after>/****************************************************************************

 This file is part of the GLC-lib library.
 Copyright (C) 2005 Laurent Ribon (laumaya@users.sourceforge.net)
 Version 0.9, packaged on Novemeber, 2005.

 http://glc-lib.sourceforge.net

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

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

 You should have received a copy of the GNU General Public License
 along with GLC-lib; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

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

//! \file glc_face.cpp implementation of the GLC_Face class.

#include <QtDebug>
#include "glc_face.h"

//////////////////////////////////////////////////////////////////////
// Constructor Destructor
//////////////////////////////////////////////////////////////////////

// Construct an empty Face
GLC_Face::GLC_Face()
:m_NbrVertex(0)
{

}

// Copy constructor
GLC_Face::GLC_Face(const GLC_Face *pFaceToCopy)
:m_NbrVertex(0)
{
	GLC_Vertex *pVertex;
	for (int i= 0; i < pFaceToCopy->GetVertexNumber(); i++)
	{
		pVertex= new GLC_Vertex(pFaceToCopy->m_Array_pVertex[i]);
		AddVertex(pVertex);
	}
}

// Delete Face's Vertexs (GLC_Vertex)
GLC_Face::~GLC_Face(void)
{

	for (int i= m_NbrVertex - 1; i >= 0; i--)
	{
		delete m_Array_pVertex[i];
	}
}
/////////////////////////////////////////////////////////////////////
// Set Functions
//////////////////////////////////////////////////////////////////////

// Add a vertex to the face
void GLC_Face::AddVertex(GLC_Vertex* pVertex)
{
	m_Array_pVertex[m_NbrVertex]= pVertex;
	m_NbrVertex++;
}

// Add an array of vertex to the face
void GLC_Face::AddVertexs(GLC_Vertex** pVertex, int Nbr)
{
	//! \todo Check vertexs number
	for (int i= 0; i < Nbr; i++)
	{
		m_Array_pVertex[m_NbrVertex + i]= pVertex[i];
	}
	m_NbrVertex+= Nbr;
}

//////////////////////////////////////////////////////////////////////
// OpenGL Functions
//////////////////////////////////////////////////////////////////////
// Face SetUp
void GLC_Face::GlDraw(void)
{
	glBegin(GL_POLYGON);
		for (int i= 0; i < m_NbrVertex; i++)
		{
			m_Array_pVertex[i]->GlDraw();
		}
	glEnd();

}
<|endoftext|>


<commit_before>// This file is part of SWGANH which is released under GPL v2.
// See file LICENSE or go to http://swganh.com/LICENSE

#include "base_swg_server.h"

#include "anh/byte_buffer.h"

#include "anh/network/soe/session.h"

using namespace swganh::network;

BaseSwgServer::BaseSwgServer(
    boost::asio::io_service& io_service)
    : anh::network::soe::Server(io_service)
{}

void BaseSwgServer::HandleMessage(
    std::shared_ptr<anh::network::soe::Session> connection,
    std::shared_ptr<anh::ByteBuffer> message)
{
    uint32_t message_type = message->peekAt<uint32_t>(message->read_position() + sizeof(uint16_t));

    auto find_iter = message_handlers_.find(message_type);
    if (find_iter == message_handlers_.end())
    {
        throw UnidentifiedMessageReceived("Received an unidentified message");
    }

    find_iter->second(connection, message);
}

void BaseSwgServer::RegisterMessageHandler(
    anh::HashString handler_id,
    SwgMessageHandler&& handler)
{
    if (HasHandler(handler_id))
    {
        throw HandlerAlreadyDefined("Requested registration of handler that has already been defined.");
    }

    message_handlers_.insert(make_pair(handler_id, move(handler)));
}

bool BaseSwgServer::HasHandler(anh::HashString handler_id)
{
    return (message_handlers_.find(handler_id) != message_handlers_.end());
}
<commit_msg>Log invalid message types and catch any exceptions that occur during handling.<commit_after>// This file is part of SWGANH which is released under GPL v2.
// See file LICENSE or go to http://swganh.com/LICENSE

#include "base_swg_server.h"

#include <boost/log/trivial.hpp>

#include "anh/byte_buffer.h"

#include "anh/network/soe/session.h"

using namespace swganh::network;

BaseSwgServer::BaseSwgServer(
    boost::asio::io_service& io_service)
    : anh::network::soe::Server(io_service)
{}

void BaseSwgServer::HandleMessage(
    std::shared_ptr<anh::network::soe::Session> connection,
    std::shared_ptr<anh::ByteBuffer> message)
{
    uint32_t message_type = message->peekAt<uint32_t>(message->read_position() + sizeof(uint16_t));

    auto find_iter = message_handlers_.find(message_type);
    if (find_iter == message_handlers_.end())
    {
        BOOST_LOG_TRIVIAL(warning) << "Received an unidentified message";
        return;
    }

    try
    {
        find_iter->second(connection, message);
    }
    catch(std::exception& e)
    {
        BOOST_LOG_TRIVIAL(error) << e.what();
    }
}

void BaseSwgServer::RegisterMessageHandler(
    anh::HashString handler_id,
    SwgMessageHandler&& handler)
{
    if (HasHandler(handler_id))
    {
        throw HandlerAlreadyDefined("Requested registration of handler that has already been defined.");
    }

    message_handlers_.insert(make_pair(handler_id, move(handler)));
}

bool BaseSwgServer::HasHandler(anh::HashString handler_id)
{
    return (message_handlers_.find(handler_id) != message_handlers_.end());
}
<|endoftext|>


<commit_before>#include "memcache_client_pool.h"

#include "vbucket_config.h"
#include "evpp/event_loop_thread_pool.h"
#include "likely.h"

namespace evmc {

#define GET_FILTER_KEY_POS(name, key) \
	name = key.find(key_filter_[0]); \
	if (name == std::string::npos) { \
		name = key.size(); \
	}

#define SET_SERVERID(vbucket,command) \
    MultiModeVbucketConfig* vbconf = vbucket_config(); \
	uint16_t server_id = vbconf->SelectServerId(vbucket, BAD_SERVER_ID); \
	command->set_server_id(server_id); \

MemcacheClientPool::~MemcacheClientPool() {
	if (loop_pool_.IsRunning()) {
		Stop(true);
	}
}

void MemcacheClientPool::Stop(bool wait_thread_exit) {
    loop_pool_.Stop(wait_thread_exit);
	MemcacheClientBase::Stop();
}

bool MemcacheClientPool::Start() {

    bool ok = loop_pool_.Start(true);

    if (UNLIKELY(!ok)) {
		LOG_ERROR << "loop pool start failed";
        return false;
    }

	if (!MemcacheClientBase::Start(true)) {
		loop_pool_.Stop(true);
		LOG_ERROR << "vbucket init failed";
        return false;
	}
    auto server_list = vbucket_config()->server_list();

    // 须先构造memc_client_map_数组，再各个元素取地址，否则地址不稳定，可能崩溃
    for (uint32_t i = 0; i < loop_pool_.thread_num(); ++i) {
        memc_client_map_.emplace_back(MemcClientMap());
        evpp::EventLoop* loop = loop_pool_.GetNextLoopWithHash(i);

        for (size_t svr = 0; svr < server_list.size(); ++svr) {
            auto & client_map = memc_client_map_.back();
			BuilderMemClient(loop, server_list[svr], client_map, timeout_ms_);
        }
    }

    for (uint32_t i = 0; i < loop_pool_.thread_num(); ++i) {
        evpp::EventLoop* loop = loop_pool_.GetNextLoopWithHash(i);
        loop->set_context(evpp::Any(&memc_client_map_[i]));
    }

    return ok;
}

void MemcacheClientPool::Set(evpp::EventLoop* caller_loop, const std::string& key, const std::string& value, uint32_t flags,
                             uint32_t expire, SetCallback callback) {

	std::size_t pos = 0;
	GET_FILTER_KEY_POS(pos, key)
    const uint16_t vbucket = vbucket_config()->GetVbucketByKey(key.c_str(), pos);
    CommandPtr command = std::make_shared<SetCommand>(caller_loop, vbucket, key, value, flags, expire, callback);
	SET_SERVERID(vbucket, command)
	LaunchCommand(command);
}

void MemcacheClientPool::Remove(evpp::EventLoop* caller_loop, const std::string& key, RemoveCallback callback) {
	std::size_t pos = 0;
	GET_FILTER_KEY_POS(pos, key)
    const uint16_t vbucket = vbucket_config()->GetVbucketByKey(key.c_str(), pos);
    CommandPtr command = std::make_shared<RemoveCommand>(caller_loop, vbucket, key, callback);
	SET_SERVERID(vbucket, command)
	LaunchCommand(command);
}

void MemcacheClientPool::Get(evpp::EventLoop* caller_loop, const std::string& key, GetCallback callback) {
	std::size_t pos = 0;
	GET_FILTER_KEY_POS(pos, key)
    const uint16_t vbucket = vbucket_config()->GetVbucketByKey(key.c_str(), pos);
    CommandPtr command = std::make_shared<GetCommand>(caller_loop, vbucket, key, callback);
	SET_SERVERID(vbucket, command)
	LaunchCommand(command);
}

void MemcacheClientPool::PrefixGet(evpp::EventLoop* caller_loop, const std::string& key, PrefixGetCallback callback) {
	std::size_t pos = 0;
	GET_FILTER_KEY_POS(pos, key)
    const uint16_t vbucket = vbucket_config()->GetVbucketByKey(key.c_str(), pos);
    CommandPtr command = std::make_shared<PrefixGetCommand>(caller_loop, vbucket, key, callback);
	SET_SERVERID(vbucket, command)
	LaunchCommand(command);
}

void MemcacheClientPool::RunBackGround(const std::function<void(void)>& fun) {
	auto loop = loop_pool_.GetNextLoopWithHash(rand());
    loop->RunInLoop(fun);
}

void MemcacheClientPool::MultiGet(evpp::EventLoop* caller_loop, std::vector<std::string>& keys, MultiGetCallback& callback) {
    if (UNLIKELY(keys.size() <= 0)) {
		MultiGetResult result;
		caller_loop->RunInLoop(std::bind(callback, std::move(result)));
        return;
    }
	const std::size_t size = keys.size();
    std::map<uint16_t, IdInfo> serverid_keys;

    MultiModeVbucketConfig* vbconf = vbucket_config();
	uint16_t vbucket = 0;
	uint16_t server_id = 0;
	MultiKeyGetHandlerPtr handler = std::make_shared<MultiKeyHandler<MultiGetResult, MultiGetCallback> > (callback);
	auto& result = handler->get_result();
	std::size_t pos = 0;
	std::vector<int> serverid_table(vbconf->server_list().size(), -1);

    for (size_t i = 0; i < size; ++i) {
		auto &key = keys[i];
		GET_FILTER_KEY_POS(pos, key)
        vbucket = vbconf->GetVbucketByKey(key.c_str(), pos);
		server_id = vbconf->SelectServerFirstId(vbucket);
		if(serverid_table[server_id] == -1) {
			serverid_table[server_id] = vbconf->SelectServerId(vbucket, BAD_SERVER_ID);
		}
		server_id = serverid_table[server_id];

		auto& item = serverid_keys[server_id];
        item.keys.emplace_back(key);
        item.vbuckets.emplace_back(vbucket);
		result.emplace(std::move(key), std::move(GetResult()));
    }
	handler->set_serverid_keys(serverid_keys);

	auto& serverid_keys_d = handler->get_serverid_keys();
    for(auto& it : serverid_keys_d) {
		server_id = it.first;
		CommandPtr command = std::make_shared<MultiGetCommand>(caller_loop, server_id, handler);
		command->set_server_id(server_id);
		LaunchCommand(command);
	}
}

void MemcacheClientPool::PrefixMultiGet(evpp::EventLoop* caller_loop, std::vector<std::string>& keys, PrefixMultiGetCallback callback) {
    if (UNLIKELY(keys.size() <= 0)) {
		PrefixMultiGetResult result;
		caller_loop->RunInLoop(std::bind(callback, std::move(result)));
        return;
    }
    MultiModeVbucketConfig* vbconf = vbucket_config();
	const std::size_t size = keys.size();
    std::map<uint16_t, IdInfo> serverid_keys;
	std::vector<int> serverid_table(vbconf->server_list().size(), -1);

	uint16_t vbucket = 0;
	uint16_t server_id = 0;
	PrefixMultiKeyGetHandlerPtr handler = std::make_shared<MultiKeyHandler<PrefixMultiGetResult, PrefixMultiGetCallback> >(callback);
	auto& result = handler->get_result();
	std::size_t pos = 0;

    for (size_t i = 0; i < size; ++i) {
		auto &key = keys[i];
		GET_FILTER_KEY_POS(pos, key)
        vbucket = vbconf->GetVbucketByKey(key.c_str(), pos);
		server_id = vbconf->SelectServerFirstId(vbucket);
		if(serverid_table[server_id] == -1) {
			serverid_table[server_id] = vbconf->SelectServerId(vbucket, BAD_SERVER_ID);
		}
		server_id = serverid_table[server_id];
		auto& item = serverid_keys[server_id];
        item.keys.emplace_back(key);
        item.vbuckets.emplace_back(vbucket);
		result.emplace(std::move(key), std::make_shared<PrefixGetResult>());
    }
	handler->set_serverid_keys(serverid_keys);

	auto & serverid_keys_d = handler->get_serverid_keys();
    for(auto& it : serverid_keys_d) {
		server_id = it.first;
		CommandPtr command = std::make_shared<PrefixMultiGetCommand>(caller_loop, server_id, handler);
		command->set_server_id(server_id);
		LaunchCommand(command);
	}
}

void MemcacheClientPool::LaunchCommand(CommandPtr& command) {
	//const int thread = next_thread_++;
	auto loop = loop_pool_.GetNextLoopWithHash(rand());
    loop->RunInLoop(
        std::bind(&MemcacheClientPool::DoLaunchCommand, this, loop, command));
}

void MemcacheClientPool::DoLaunchCommand(evpp::EventLoop * loop, CommandPtr command) {
    MultiModeVbucketConfig* vbconf = vbucket_config();

	uint16_t server_id = command->server_id();
	if (UNLIKELY(!command->ShouldRetry())) { //重试 需要重新算serverid
		uint16_t vbucket = command->vbucket_id();
		server_id = vbconf->SelectServerId(vbucket, command->server_id());
		if (UNLIKELY(server_id == BAD_SERVER_ID)) {
			LOG_ERROR << "bad server id";
			command->OnError(ERR_CODE_DISCONNECT);
			return;
		}
		LOG_ERROR << "old value:" << command->server_id() << " new value:" << server_id;
		//command->set_server_id(server_id);
	}

    std::string server_addr = vbconf->GetServerAddrById(server_id);
    MemcClientMap* client_map = GetMemcClientMap(loop);

    if (UNLIKELY(client_map == NULL)) {
        command->OnError(ERR_CODE_DISCONNECT);
        LOG_INFO << "DoLaunchCommand thread pool empty";
        return;
    }

    auto it = client_map->find(server_addr);

    if (UNLIKELY(it == client_map->end())) {
		BuilderMemClient(loop, server_addr, *client_map, timeout_ms_);
		auto client = client_map->find(server_addr);
		client->second->PushWaitingCommand(command);
        return;
    }

	if (LIKELY(it->second->conn() && it->second->conn()->IsConnected())) {
        it->second->PushRunningCommand(command);
        command->Launch(it->second);
		return;
	}

    if (!it->second->conn() || it->second->conn()->status() == evpp::TCPConn::kConnecting) {
        it->second->PushWaitingCommand(command);
    } else {
        if (command->ShouldRetry()) {
            LOG_INFO << "OnClientConnection disconnect retry";
			command->set_server_id(command->server_id());
            LaunchCommand(command);
        } else {
            command->OnError(ERR_CODE_DISCONNECT);
        }
    }
}
}

<commit_msg>delte some log<commit_after>#include "memcache_client_pool.h"

#include "vbucket_config.h"
#include "evpp/event_loop_thread_pool.h"
#include "likely.h"

namespace evmc {

#define GET_FILTER_KEY_POS(name, key) \
	name = key.find(key_filter_[0]); \
	if (name == std::string::npos) { \
		name = key.size(); \
	}

#define SET_SERVERID(vbucket,command) \
    MultiModeVbucketConfig* vbconf = vbucket_config(); \
	uint16_t server_id = vbconf->SelectServerId(vbucket, BAD_SERVER_ID); \
	command->set_server_id(server_id); \

MemcacheClientPool::~MemcacheClientPool() {
	if (loop_pool_.IsRunning()) {
		Stop(true);
	}
}

void MemcacheClientPool::Stop(bool wait_thread_exit) {
    loop_pool_.Stop(wait_thread_exit);
	MemcacheClientBase::Stop();
}

bool MemcacheClientPool::Start() {

    bool ok = loop_pool_.Start(true);

    if (UNLIKELY(!ok)) {
		LOG_ERROR << "loop pool start failed";
        return false;
    }

	if (!MemcacheClientBase::Start(true)) {
		loop_pool_.Stop(true);
		LOG_ERROR << "vbucket init failed";
        return false;
	}
    auto server_list = vbucket_config()->server_list();

    // 须先构造memc_client_map_数组，再各个元素取地址，否则地址不稳定，可能崩溃
    for (uint32_t i = 0; i < loop_pool_.thread_num(); ++i) {
        memc_client_map_.emplace_back(MemcClientMap());
        evpp::EventLoop* loop = loop_pool_.GetNextLoopWithHash(i);

        for (size_t svr = 0; svr < server_list.size(); ++svr) {
            auto & client_map = memc_client_map_.back();
			BuilderMemClient(loop, server_list[svr], client_map, timeout_ms_);
        }
    }

    for (uint32_t i = 0; i < loop_pool_.thread_num(); ++i) {
        evpp::EventLoop* loop = loop_pool_.GetNextLoopWithHash(i);
        loop->set_context(evpp::Any(&memc_client_map_[i]));
    }

    return ok;
}

void MemcacheClientPool::Set(evpp::EventLoop* caller_loop, const std::string& key, const std::string& value, uint32_t flags,
                             uint32_t expire, SetCallback callback) {

	std::size_t pos = 0;
	GET_FILTER_KEY_POS(pos, key)
    const uint16_t vbucket = vbucket_config()->GetVbucketByKey(key.c_str(), pos);
    CommandPtr command = std::make_shared<SetCommand>(caller_loop, vbucket, key, value, flags, expire, callback);
	SET_SERVERID(vbucket, command)
	LaunchCommand(command);
}

void MemcacheClientPool::Remove(evpp::EventLoop* caller_loop, const std::string& key, RemoveCallback callback) {
	std::size_t pos = 0;
	GET_FILTER_KEY_POS(pos, key)
    const uint16_t vbucket = vbucket_config()->GetVbucketByKey(key.c_str(), pos);
    CommandPtr command = std::make_shared<RemoveCommand>(caller_loop, vbucket, key, callback);
	SET_SERVERID(vbucket, command)
	LaunchCommand(command);
}

void MemcacheClientPool::Get(evpp::EventLoop* caller_loop, const std::string& key, GetCallback callback) {
	std::size_t pos = 0;
	GET_FILTER_KEY_POS(pos, key)
    const uint16_t vbucket = vbucket_config()->GetVbucketByKey(key.c_str(), pos);
    CommandPtr command = std::make_shared<GetCommand>(caller_loop, vbucket, key, callback);
	SET_SERVERID(vbucket, command)
	LaunchCommand(command);
}

void MemcacheClientPool::PrefixGet(evpp::EventLoop* caller_loop, const std::string& key, PrefixGetCallback callback) {
	std::size_t pos = 0;
	GET_FILTER_KEY_POS(pos, key)
    const uint16_t vbucket = vbucket_config()->GetVbucketByKey(key.c_str(), pos);
    CommandPtr command = std::make_shared<PrefixGetCommand>(caller_loop, vbucket, key, callback);
	SET_SERVERID(vbucket, command)
	LaunchCommand(command);
}

void MemcacheClientPool::RunBackGround(const std::function<void(void)>& fun) {
	auto loop = loop_pool_.GetNextLoopWithHash(rand());
    loop->RunInLoop(fun);
}

void MemcacheClientPool::MultiGet(evpp::EventLoop* caller_loop, std::vector<std::string>& keys, MultiGetCallback& callback) {
    if (UNLIKELY(keys.size() <= 0)) {
		MultiGetResult result;
		caller_loop->RunInLoop(std::bind(callback, std::move(result)));
        return;
    }
	const std::size_t size = keys.size();
    std::map<uint16_t, IdInfo> serverid_keys;

    MultiModeVbucketConfig* vbconf = vbucket_config();
	uint16_t vbucket = 0;
	uint16_t server_id = 0;
	MultiKeyGetHandlerPtr handler = std::make_shared<MultiKeyHandler<MultiGetResult, MultiGetCallback> > (callback);
	auto& result = handler->get_result();
	std::size_t pos = 0;
	std::vector<int> serverid_table(vbconf->server_list().size(), -1);

    for (size_t i = 0; i < size; ++i) {
		auto &key = keys[i];
		GET_FILTER_KEY_POS(pos, key)
        vbucket = vbconf->GetVbucketByKey(key.c_str(), pos);
		server_id = vbconf->SelectServerFirstId(vbucket);
		if(serverid_table[server_id] == -1) {
			serverid_table[server_id] = vbconf->SelectServerId(vbucket, BAD_SERVER_ID);
		}
		server_id = serverid_table[server_id];

		auto& item = serverid_keys[server_id];
        item.keys.emplace_back(key);
        item.vbuckets.emplace_back(vbucket);
		result.emplace(std::move(key), std::move(GetResult()));
    }
	handler->set_serverid_keys(serverid_keys);

	auto& serverid_keys_d = handler->get_serverid_keys();
    for(auto& it : serverid_keys_d) {
		server_id = it.first;
		CommandPtr command = std::make_shared<MultiGetCommand>(caller_loop, server_id, handler);
		command->set_server_id(server_id);
		LaunchCommand(command);
	}
}

void MemcacheClientPool::PrefixMultiGet(evpp::EventLoop* caller_loop, std::vector<std::string>& keys, PrefixMultiGetCallback callback) {
    if (UNLIKELY(keys.size() <= 0)) {
		PrefixMultiGetResult result;
		caller_loop->RunInLoop(std::bind(callback, std::move(result)));
        return;
    }
    MultiModeVbucketConfig* vbconf = vbucket_config();
	const std::size_t size = keys.size();
    std::map<uint16_t, IdInfo> serverid_keys;
	std::vector<int> serverid_table(vbconf->server_list().size(), -1);

	uint16_t vbucket = 0;
	uint16_t server_id = 0;
	PrefixMultiKeyGetHandlerPtr handler = std::make_shared<MultiKeyHandler<PrefixMultiGetResult, PrefixMultiGetCallback> >(callback);
	auto& result = handler->get_result();
	std::size_t pos = 0;

    for (size_t i = 0; i < size; ++i) {
		auto &key = keys[i];
		GET_FILTER_KEY_POS(pos, key)
        vbucket = vbconf->GetVbucketByKey(key.c_str(), pos);
		server_id = vbconf->SelectServerFirstId(vbucket);
		if(serverid_table[server_id] == -1) {
			serverid_table[server_id] = vbconf->SelectServerId(vbucket, BAD_SERVER_ID);
		}
		server_id = serverid_table[server_id];
		auto& item = serverid_keys[server_id];
        item.keys.emplace_back(key);
        item.vbuckets.emplace_back(vbucket);
		result.emplace(std::move(key), std::make_shared<PrefixGetResult>());
    }
	handler->set_serverid_keys(serverid_keys);

	auto & serverid_keys_d = handler->get_serverid_keys();
    for(auto& it : serverid_keys_d) {
		server_id = it.first;
		CommandPtr command = std::make_shared<PrefixMultiGetCommand>(caller_loop, server_id, handler);
		command->set_server_id(server_id);
		LaunchCommand(command);
	}
}

void MemcacheClientPool::LaunchCommand(CommandPtr& command) {
	//const int thread = next_thread_++;
	auto loop = loop_pool_.GetNextLoopWithHash(rand());
    loop->RunInLoop(
        std::bind(&MemcacheClientPool::DoLaunchCommand, this, loop, command));
}

void MemcacheClientPool::DoLaunchCommand(evpp::EventLoop * loop, CommandPtr command) {
    MultiModeVbucketConfig* vbconf = vbucket_config();

	uint16_t server_id = command->server_id();
	if (UNLIKELY(!command->ShouldRetry())) { //重试 需要重新算serverid
		uint16_t vbucket = command->vbucket_id();
		server_id = vbconf->SelectServerId(vbucket, command->server_id());
		if (UNLIKELY(server_id == BAD_SERVER_ID)) {
			LOG_ERROR << "bad server id";
			command->OnError(ERR_CODE_DISCONNECT);
			return;
		}
	}

    std::string server_addr = vbconf->GetServerAddrById(server_id);
    MemcClientMap* client_map = GetMemcClientMap(loop);

    if (UNLIKELY(client_map == NULL)) {
        command->OnError(ERR_CODE_DISCONNECT);
        LOG_INFO << "DoLaunchCommand thread pool empty";
        return;
    }

    auto it = client_map->find(server_addr);

    if (UNLIKELY(it == client_map->end())) {
		BuilderMemClient(loop, server_addr, *client_map, timeout_ms_);
		auto client = client_map->find(server_addr);
		client->second->PushWaitingCommand(command);
        return;
    }

	if (LIKELY(it->second->conn() && it->second->conn()->IsConnected())) {
        it->second->PushRunningCommand(command);
        command->Launch(it->second);
		return;
	}

    if (!it->second->conn() || it->second->conn()->status() == evpp::TCPConn::kConnecting) {
        it->second->PushWaitingCommand(command);
    } else {
        if (command->ShouldRetry()) {
            LOG_INFO << "OnClientConnection disconnect retry";
			command->set_server_id(command->server_id());
            LaunchCommand(command);
        } else {
            command->OnError(ERR_CODE_DISCONNECT);
        }
    }
}
}

<|endoftext|>


<commit_before>
#include "../softbreeze.h"
#include "../math/vector3.h"
#include "../math/matrix3.h"
#include "../math/matrix4.h"
#include "../math/utility.h"
#include "camera.h"
//#include "Utilities.h"

softbreeze_namespace_beg

Camera::Camera()
{
	direction = Vector3(0, 0, 1);

	uvn = Matrix4(	1, 0, 0, 0,
					0, 1, 0, 0,
					0, 0, 1, 0,
					0, 0, 0, 0);

}

Camera::~Camera()
{

}

void Camera::SetPos(const Vector3& pos)
{
	this->pos = pos;
}

void Camera::Move(Vector3 offset)
{
	pos += offset;
}

namespace
{

	Matrix4 MakeRotationMatrixAlongVector(const Vector4& vec, float angle)
	{
		float radian = AngleToRadian(angle);
		float cs = cos(radian);
		float sn = sin(radian);

		float x = vec.x, y = vec.y, z = vec.z;

		Matrix4 matrix(	x*x*(1 - cs) + sn,		x*y*(1 - cs) + x*sn,	x*z*(1 - cs) - y*sn,	0,
						x*y*(1 - cs) - z*sn,	y*y*(1 - cs) + cs,		y*z*(1 - cs) + x*sn,	0,
						x*z*(1 - cs) - y*sn,	y*z*(1 - cs) - x*sn,	z*z*(1 - cs) + cs,		0,
						0,						0,						0,						1);

		return matrix;
	}

}

void Camera::Pitch(float angle)
{
	Vector4& u = uvn.data[0];
	Vector4& v = uvn.data[1];
	Vector4& n = uvn.data[2];

	Matrix4 matrix = MakeRotationMatrixAlongVector(u, angle);

	v = v*matrix;
	v.Normalize();
	n = n*matrix;
	n.Normalize();

	direction.x=n.x;
	direction.y=n.y;
	direction.z=n.z;
}

void Camera::Yaw(float angle)
{
	Vector4& u = uvn.data[0];
	Vector4& v = uvn.data[1];
	Vector4& n = uvn.data[2];

	Matrix4 matrix = MakeRotationMatrixAlongVector(v, angle);

	u = u*matrix;
	u.Normalize();
	n = n*matrix;
	n.Normalize();

	direction.x=n.x;
	direction.y=n.y;
	direction.z=n.z;
}

void Camera::Roll(float angle)
{
	Vector4& u = uvn.data[0];
	Vector4& v = uvn.data[1];
	Vector4& n = uvn.data[2];

	Matrix4 matrix = MakeRotationMatrixAlongVector(n, angle);

	u = u*matrix;
	u.Normalize();
	v = v*matrix;
	v.Normalize();
}

softbreeze_namespace_end<commit_msg>fulfill the class Camera<commit_after>
#include "../softbreeze.h"
#include "../math/vector3.h"
#include "../math/matrix3.h"
#include "../math/matrix4.h"
#include "../math/utility.h"
#include "camera.h"
//#include "Utilities.h"

softbreeze_namespace_beg

Camera::Camera()
{
	direction = Vector3(0, 0, 1);

	uvn = Matrix4(	1, 0, 0, 0,
					0, 1, 0, 0,
					0, 0, 1, 0,
					0, 0, 0, 0);

}

Camera::~Camera()
{

}

void Camera::SetPos(const Vector3& pos)
{
	this->pos = pos;
}

void Camera::Move(Vector3 offset)
{
	pos += offset;
}

namespace
{

	Matrix4 MakeRotationMatrixAlongVector(const Vector4& vec, float angle)
	{
		float radian = AngleToRadian(angle);
		float cs = cos(radian);
		float sn = sin(radian);

		float x = vec.x, y = vec.y, z = vec.z;

		Matrix4 matrix(	x*x*(1 - cs) + sn,		x*y*(1 - cs) + x*sn,	x*z*(1 - cs) - y*sn,	0,
						x*y*(1 - cs) - z*sn,	y*y*(1 - cs) + cs,		y*z*(1 - cs) + x*sn,	0,
						x*z*(1 - cs) - y*sn,	y*z*(1 - cs) - x*sn,	z*z*(1 - cs) + cs,		0,
						0,						0,						0,						1);

		return matrix;
	}

}

void Camera::Pitch(float angle)
{
	Vector4& u = uvn.data[0];
	Vector4& v = uvn.data[1];
	Vector4& n = uvn.data[2];

	Matrix4 matrix = MakeRotationMatrixAlongVector(u, angle);

	v = v*matrix;
	v.Normalize();
	n = n*matrix;
	n.Normalize();

	direction.x=n.x;
	direction.y=n.y;
	direction.z=n.z;
}

void Camera::Yaw(float angle)
{
	Vector4& u = uvn.data[0];
	Vector4& v = uvn.data[1];
	Vector4& n = uvn.data[2];

	Matrix4 matrix = MakeRotationMatrixAlongVector(v, angle);

	u = u*matrix;
	u.Normalize();
	n = n*matrix;
	n.Normalize();

	direction.x=n.x;
	direction.y=n.y;
	direction.z=n.z;
}

void Camera::Roll(float angle)
{
	Vector4& u = uvn.data[0];
	Vector4& v = uvn.data[1];
	Vector4& n = uvn.data[2];

	Matrix4 matrix = MakeRotationMatrixAlongVector(n, angle);

	u = u*matrix;
	u.Normalize();
	v = v*matrix;
	v.Normalize();
}

Matrix4	Camera::MakeCameraMatrix()
{
	const Vector4& u = uvn.data[0];
	const Vector4& v = uvn.data[1];
	const Vector4& n = uvn.data[2];
	Vector4 cameraPos(pos.x, pos.y, pos.z, 0);

	Matrix4 matrix( u.x,				v.x,				n.x,				0,
					u.y,				v.y,				n.y,				0,
					u.z,				v.z,				n.z,				0,
					-cameraPos.Dot(u),	-cameraPos.Dot(v),	-cameraPos.Dot(n),	1);

	return matrix;
}

softbreeze_namespace_end<|endoftext|>


<commit_before>/*
Copyright (c) 2015 Intel Corporation.  All right reserved.

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

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

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/

#include "Arduino.h"
#include "pins_arduino.h"
#include "interrupt.h"
#include "conf.h"
#include "aux_regs.h"

#define ACTIVE 1
#define INACTIVE 0
#define CONVERT_US 1000000

/* globals */
static uint32_t current_pin;
static uint32_t timer_interval;
static int32_t duration_left;
static uint32_t tone_state = INACTIVE;

#ifdef __cplusplus
 extern "C" {
#endif

static void timer1_disable_tone(void);
static void timer1_isr(void);
static void timer1_init_tone(uint32_t ticktime_us);

static void timer1_disable_tone(void)
{
    uint32_t saved;
    uint32_t ctrl_val;   /* timer control register value */

    saved = interrupt_lock();

    /* disable interrupt generation */
    ctrl_val = aux_reg_read(ARC_V2_TMR1_CONTROL);
    aux_reg_write(ARC_V2_TMR1_CONTROL, ctrl_val & ~ARC_V2_TMR_CTRL_IE);

    interrupt_unlock(saved);

    /* disable interrupt in the interrupt controller */
    interrupt_disable(ARCV2_IRQ_TIMER1);
}

static void timer1_isr(void)
{
    static uint32_t pin_state = 0;

    /* clear the interrupt (by writing 0 to IP bit of the control register) */
    aux_reg_write(ARC_V2_TMR1_CONTROL, ARC_V2_TMR_CTRL_NH | ARC_V2_TMR_CTRL_IE);

    if (duration_left != 0) {
        pin_state = !pin_state;
        digitalWrite(current_pin, pin_state);
        if (duration_left > 0)
            duration_left--;
    } else {
        timer1_disable_tone();
        digitalWrite(current_pin,LOW);
    }
}

static void timer1_init_tone(uint32_t ticktime_us)
{
    int tickunit;

    /* ensure that the timer will not generate interrupts */
    aux_reg_write(ARC_V2_TMR1_CONTROL, 0);
    aux_reg_write(ARC_V2_TMR1_COUNT, 0);    /* clear the count value */

    /* connect specified routine/parameter to the timer 0 interrupt vector */
    interrupt_connect(ARCV2_IRQ_TIMER1, timer1_isr);

    tickunit = 32 * ticktime_us;

    /*
     * Set the reload value to achieve the configured tick rate, enable the
     * counter and interrupt generation.
     *
     * The global variable 'tickunit' represents the #cycles/tick.
     */

    aux_reg_write(ARC_V2_TMR1_LIMIT, tickunit); /* write the limit value */
    /* count only when not halted for debug and enable interrupts */
    aux_reg_write(ARC_V2_TMR1_CONTROL, ARC_V2_TMR_CTRL_NH | ARC_V2_TMR_CTRL_IE);
    aux_reg_write(ARC_V2_TMR1_COUNT, 0); /* write the start value */

    /* Everything has been configured. It is now safe to enable the interrupt */
    interrupt_enable(ARCV2_IRQ_TIMER1);
}

#ifdef __cplusplus
}
#endif

void tone(uint32_t _pin, unsigned int frequency, unsigned long duration)
{
    timer_interval = (CONVERT_US / frequency) >> 1;

    if (timer_interval == 0) {
        return;
    }

    /* duration of tone is never-ending, until a noTone() is called, unless a non-zero duration is specified by the caller */
    if (duration > 0) {
        duration *= 1000;
        duration_left = duration / timer_interval;
    } else {
        duration_left = -1;
    }

    if (tone_state == ACTIVE) {
        /* if tone already active on another pin, just return */
        if (current_pin != _pin) {
            return;
        } else { /*If the tone is playing on the same pin, set its frequency.*/
            timer1_disable_tone();
            pinMode(_pin, OUTPUT);
            timer1_init_tone(timer_interval);
        }
    } else { /*  set the pin as output, and configure the timer (init) to set the frequency (of the timer callbacks) */
        tone_state = ACTIVE;
        current_pin = _pin;
        pinMode(_pin, OUTPUT);
        timer1_init_tone(timer_interval);
    }
}

void noTone(uint32_t _pin)
{
    /* if tone already active on specified pin, disable the timer */
    if (current_pin == _pin) {
        timer1_disable_tone();
        digitalWrite(_pin, 0);
        tone_state = INACTIVE;
    }
}
<commit_msg>ATLEDGE-209 tone() bug when frequency = 0<commit_after>/*
Copyright (c) 2015 Intel Corporation.  All right reserved.

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

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

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/

#include "Arduino.h"
#include "pins_arduino.h"
#include "interrupt.h"
#include "conf.h"
#include "aux_regs.h"

#define ACTIVE 1
#define INACTIVE 0
#define CONVERT_US 1000000

/* globals */
static uint32_t current_pin;
static uint32_t timer_interval;
static int32_t duration_left;
static uint32_t tone_state = INACTIVE;

#ifdef __cplusplus
 extern "C" {
#endif

static void timer1_disable_tone(void);
static void timer1_isr(void);
static void timer1_init_tone(uint32_t ticktime_us);

static void timer1_disable_tone(void)
{
    uint32_t saved;
    uint32_t ctrl_val;   /* timer control register value */

    saved = interrupt_lock();

    /* disable interrupt generation */
    ctrl_val = aux_reg_read(ARC_V2_TMR1_CONTROL);
    aux_reg_write(ARC_V2_TMR1_CONTROL, ctrl_val & ~ARC_V2_TMR_CTRL_IE);

    interrupt_unlock(saved);

    /* disable interrupt in the interrupt controller */
    interrupt_disable(ARCV2_IRQ_TIMER1);
}

static void timer1_isr(void)
{
    static uint32_t pin_state = 0;

    /* clear the interrupt (by writing 0 to IP bit of the control register) */
    aux_reg_write(ARC_V2_TMR1_CONTROL, ARC_V2_TMR_CTRL_NH | ARC_V2_TMR_CTRL_IE);

    if (duration_left != 0) {
        pin_state = !pin_state;
        digitalWrite(current_pin, pin_state);
        if (duration_left > 0)
            duration_left--;
    } else {
        timer1_disable_tone();
        digitalWrite(current_pin,LOW);
    }
}

static void timer1_init_tone(uint32_t ticktime_us)
{
    int tickunit;

    /* ensure that the timer will not generate interrupts */
    aux_reg_write(ARC_V2_TMR1_CONTROL, 0);
    aux_reg_write(ARC_V2_TMR1_COUNT, 0);    /* clear the count value */

    /* connect specified routine/parameter to the timer 0 interrupt vector */
    interrupt_connect(ARCV2_IRQ_TIMER1, timer1_isr);

    tickunit = 32 * ticktime_us;

    /*
     * Set the reload value to achieve the configured tick rate, enable the
     * counter and interrupt generation.
     *
     * The global variable 'tickunit' represents the #cycles/tick.
     */

    aux_reg_write(ARC_V2_TMR1_LIMIT, tickunit); /* write the limit value */
    /* count only when not halted for debug and enable interrupts */
    aux_reg_write(ARC_V2_TMR1_CONTROL, ARC_V2_TMR_CTRL_NH | ARC_V2_TMR_CTRL_IE);
    aux_reg_write(ARC_V2_TMR1_COUNT, 0); /* write the start value */

    /* Everything has been configured. It is now safe to enable the interrupt */
    interrupt_enable(ARCV2_IRQ_TIMER1);
}

#ifdef __cplusplus
}
#endif

void tone(uint32_t _pin, unsigned int frequency, unsigned long duration)
{
    if(frequency != 0) {
        timer_interval = (CONVERT_US / frequency) >> 1;
    } else
        return;

    /* duration of tone is never-ending, until a noTone() is called, unless a non-zero duration is specified by the caller */
    if (duration > 0) {
        duration *= 1000;
        duration_left = duration / timer_interval;
    } else {
        duration_left = -1;
    }

    if (tone_state == ACTIVE) {
        /* if tone already active on another pin, just return */
        if (current_pin != _pin) {
            return;
        } else { /*If the tone is playing on the same pin, set its frequency.*/
            timer1_disable_tone();
            pinMode(_pin, OUTPUT);
            timer1_init_tone(timer_interval);
        }
    } else { /*  set the pin as output, and configure the timer (init) to set the frequency (of the timer callbacks) */
        tone_state = ACTIVE;
        current_pin = _pin;
        pinMode(_pin, OUTPUT);
        timer1_init_tone(timer_interval);
    }
}

void noTone(uint32_t _pin)
{
    /* if tone already active on specified pin, disable the timer */
    if (current_pin == _pin) {
        timer1_disable_tone();
        digitalWrite(_pin, 0);
        tone_state = INACTIVE;
    }
}
<|endoftext|>