text:
/*
 * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
 */

#include <fstream>
#include <iostream>

#include <boost/asio/ip/host_name.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/program_options.hpp>
#include <pthread.h>

#include "base/logging.h"
#include "base/cpuinfo.h"
#include "bgp/bgp_config.h"
#include "bgp/bgp_config_parser.h"
#include "bgp/bgp_peer.h"
#include "bgp/bgp_peer_types.h"
#include "bgp/bgp_server.h"
#include "bgp/bgp_session_manager.h"
#include "bgp/bgp_xmpp_channel.h"
#include "bgp/routing-instance/routing_instance.h"
#include "control-node/control_node.h"
#include "db/db_graph.h"
#include "ifmap/ifmap_link_table.h"
#include "ifmap/ifmap_server_parser.h"
#include "ifmap/ifmap_server.h"
#include "ifmap/ifmap_xmpp.h"
#include "ifmap/client/ifmap_manager.h"
#include "io/event_manager.h"
#include "sandesh/sandesh_types.h"
#include "sandesh/sandesh.h"
#include "sandesh/sandesh_http.h"
#include "sandesh/sandesh_trace.h"
#include "sandesh/common/vns_types.h"
#include "sandesh/common/vns_constants.h"
#include "schema/vnc_cfg_types.h"
#include "xmpp/xmpp_init.h"
#include "xmpp/xmpp_server.h"
#include "xmpp/sandesh/xmpp_peer_info_types.h"
#include "bgp/bgp_sandesh.h"
#include "base/contrail_ports.h"
#include "base/misc_utils.h"
#include "control-node/sandesh/control_node_types.h"
#include <control-node/buildinfo.h>
#include "discovery_client.h"

using namespace std;
using boost::system::error_code;
using namespace boost::asio::ip;
namespace opt = boost::program_options;

static TaskTrigger *node_info_trigger;
static Timer *node_info_log_timer;
static uint64_t start_time;
static EventManager evm;

static string FileRead(const char *filename) {
    ifstream file(filename);
    string content((istreambuf_iterator<char>(file)),
                   istreambuf_iterator<char>());
    return content;
}

static void IFMap_Initialize(IFMapServer *server) {
    IFMapLinkTable_Init(server->database(), server->graph());
    IFMapServerParser *parser = IFMapServerParser::GetInstance("vnc_cfg");
    vnc_cfg_ParserInit(parser);
    vnc_cfg_Server_ModuleInit(server->database(), server->graph());
    bgp_schema_ParserInit(parser);
    bgp_schema_Server_ModuleInit(server->database(), server->graph());
    server->Initialize();
}

static void WaitForIdle() {
    static const int kTimeout = 15;
    TaskScheduler *scheduler = TaskScheduler::GetInstance();

    for (int i = 0; i < (kTimeout * 1000); i++) {
        if (scheduler->IsEmpty()) {
            break;
        }
        usleep(1000);
    }
}

static void ShutdownDiscoveryClient(DiscoveryServiceClient *client) {
    if (client) {
        client->Shutdown();
        delete client;
    }
}

// Shutdown various server objects used in the control-node.
static void ShutdownServers(
                boost::scoped_ptr<BgpXmppChannelManager> *channel_manager,
                DiscoveryServiceClient *dsclient) {

    // Bring down bgp server, xmpp server, etc. in the right order.
    BgpServer *bgp_server = (*channel_manager)->bgp_server();
    XmppServer *xmpp_server = (*channel_manager)->xmpp_server();

    int cnt;

    // Shutdown Xmpp server first.
    xmpp_server->Shutdown();
    WaitForIdle();

    // Wait until all XMPP connections are cleaned up.
    for (cnt = 0; xmpp_server->ConnectionsCount() != 0 && cnt < 15; cnt++) {
        sleep(1);
    }

    // Shutdown BGP server.
    bgp_server->Shutdown();
    WaitForIdle();

    // Wait until all routing-instances are cleaned up.
    for (cnt = 0; bgp_server->routing_instance_mgr()->count() != 0 && cnt < 15;
            cnt++) {
        sleep(1);
    }

    channel_manager->reset();
    TcpServerManager::DeleteServer(xmpp_server);
    TimerManager::DeleteTimer(node_info_log_timer);
    delete node_info_trigger;

    //Shutdown Discovery Service Client
    ShutdownDiscoveryClient(dsclient);

    // Do sandesh cleanup.
    Sandesh::Uninit();
    WaitForIdle();
    SandeshHttp::Uninit();
    WaitForIdle();
}

bool ControlNodeInfoLogTimer() {
    node_info_trigger->Set();
    return false;
}

bool ControlNodeVersion(string &build_info_str) {
    return MiscUtils::GetBuildInfo(MiscUtils::ControlNode, BuildInfo, build_info_str);
}

static void FillProtoStats(IPeerDebugStats::ProtoStats &stats,
                           PeerProtoStats &proto_stats) {
    proto_stats.open = stats.open;
    proto_stats.keepalive = stats.keepalive;
    proto_stats.close = stats.close;
    proto_stats.update = stats.update;
    proto_stats.notification = stats.notification;
    proto_stats.total = stats.open + stats.keepalive + stats.close +
        stats.update + stats.notification;
}

static void FillRouteUpdateStats(IPeerDebugStats::UpdateStats &stats,
                                 PeerUpdateStats &rt_stats) {
    rt_stats.total = stats.total;
    rt_stats.reach = stats.reach;
    rt_stats.unreach = stats.unreach;
}

static void FillPeerDebugStats(IPeerDebugStats *peer_state,
                          PeerStatsInfo &stats) {
    PeerProtoStats proto_stats_tx;
    PeerProtoStats proto_stats_rx;
    PeerUpdateStats rt_stats_rx;
    PeerUpdateStats rt_stats_tx;

    IPeerDebugStats::ProtoStats stats_rx;
    peer_state->GetRxProtoStats(stats_rx);
    FillProtoStats(stats_rx, proto_stats_rx);

    IPeerDebugStats::ProtoStats stats_tx;
    peer_state->GetTxProtoStats(stats_tx);
    FillProtoStats(stats_tx, proto_stats_tx);

    IPeerDebugStats::UpdateStats update_stats_rx;
    peer_state->GetRxRouteUpdateStats(update_stats_rx);
    FillRouteUpdateStats(update_stats_rx, rt_stats_rx);

    IPeerDebugStats::UpdateStats update_stats_tx;
    peer_state->GetTxRouteUpdateStats(update_stats_tx);
    FillRouteUpdateStats(update_stats_tx, rt_stats_tx);

    stats.set_rx_proto_stats(proto_stats_rx);
    stats.set_tx_proto_stats(proto_stats_tx);
    stats.set_rx_update_stats(rt_stats_rx);
    stats.set_tx_update_stats(rt_stats_tx);
}

void FillXmppPeerStats(BgpServer *server, BgpXmppChannel *channel) {
    PeerStatsInfo stats;
    FillPeerDebugStats(channel->Peer()->peer_stats(), stats);

    XmppPeerInfoData peer_info;
    peer_info.set_name(channel->Peer()->ToUVEKey());
    peer_info.set_peer_stats_info(stats);
    XMPPPeerInfo::Send(peer_info);
}

void FillBgpPeerStats(BgpServer *server, BgpPeer *peer) {
    PeerStatsInfo stats;
    FillPeerDebugStats(peer->peer_stats(), stats);

    BgpPeerInfoData peer_info;
    peer_info.set_name(peer->ToUVEKey());
    peer_info.set_peer_stats_info(stats);
    BGPPeerInfo::Send(peer_info);
}

void LogControlNodePeerStats(BgpServer *server,
                             BgpXmppChannelManager *xmpp_channel_mgr) {
    xmpp_channel_mgr->VisitChannels(boost::bind(FillXmppPeerStats,
                                                server, _1));
    server->VisitBgpPeers(boost::bind(FillBgpPeerStats, server, _1));
}

bool ControlNodeInfoLogger(BgpSandeshContext &ctx) {
    BgpServer *server = ctx.bgp_server;
    BgpXmppChannelManager *xmpp_channel_mgr = ctx.xmpp_peer_manager;

    LogControlNodePeerStats(server, xmpp_channel_mgr);

    BgpRouterState state;
    static BgpRouterState prev_state;
    static bool first = true, build_info_set = false;
    bool change = false;

    CpuLoadInfo cpu_load_info;
    CpuLoadData::FillCpuInfo(cpu_load_info, false);
    state.set_name(server->localname());
    if (first) {
        state.set_uptime(start_time);
        vector<string> ip_list;
        ip_list.push_back(ControlNode::GetSelfIp());
        state.set_bgp_router_ip_list(ip_list);
        vector<string> list;
        MiscUtils::GetCoreFileList(ControlNode::GetProgramName(), list);
        if (list.size()) {
            state.set_core_files_list(list);
        }
    }
    if (!build_info_set) {
        string build_info;
        build_info_set = ControlNodeVersion(build_info);
        if (build_info != prev_state.get_build_info()) {
            state.set_build_info(build_info);
            prev_state.set_build_info(build_info);
            change = true;
        }
    }

    if (cpu_load_info != prev_state.get_cpu_info() || first) {
        state.set_cpu_info(cpu_load_info);
        if (cpu_load_info.get_cpu_share() != prev_state.get_cpu_info().get_cpu_share()) {
            state.set_cpu_share(cpu_load_info.get_cpu_share());
        }
        if (prev_state.get_cpu_info().get_meminfo() != cpu_load_info.get_meminfo()) {
            state.set_virt_mem(cpu_load_info.get_meminfo().get_virt());
        }
        prev_state.set_cpu_info(cpu_load_info);
        change = true;
    }

    uint32_t num_xmpp = xmpp_channel_mgr->count();
    if (num_xmpp != prev_state.get_num_xmpp_peer() || first) {
        state.set_num_xmpp_peer(num_xmpp);
        prev_state.set_num_xmpp_peer(num_xmpp);
        change = true;
    }

    uint32_t num_up_xmpp = xmpp_channel_mgr->NumUpPeer();
    if (num_up_xmpp != prev_state.get_num_up_xmpp_peer() || first) {
        state.set_num_up_xmpp_peer(num_up_xmpp);
        prev_state.set_num_up_xmpp_peer(num_up_xmpp);
        change = true;
    }

    uint32_t num_bgp = server->num_bgp_peer();
    if (num_bgp != prev_state.get_num_bgp_peer() || first) {
        state.set_num_bgp_peer(num_bgp);
        prev_state.set_num_bgp_peer(num_bgp);
        change = true;
    }

    uint32_t num_up_bgp_peer = server->NumUpPeer();
    if (num_up_bgp_peer != prev_state.get_num_up_bgp_peer() || first) {
        state.set_num_up_bgp_peer(num_up_bgp_peer);
        prev_state.set_num_up_bgp_peer(num_up_bgp_peer);
        change = true;
    }

    uint32_t num_ri = server->num_routing_instance();
    if (num_ri != prev_state.get_num_routing_instance() || first) {
        state.set_num_routing_instance(num_ri);
        prev_state.set_num_routing_instance(num_ri);
        change = true;
    }

    IFMapPeerServerInfo server_info;
    ctx.ifmap_server->get_ifmap_manager()->GetPeerServerInfo(server_info);
    if (server_info != prev_state.get_ifmap_info() || first) {
        state.set_ifmap_info(server_info);
        prev_state.set_ifmap_info(server_info);
        change = true;
    }

    uint32_t out_load = server->get_output_queue_depth();
    if (out_load != prev_state.get_output_queue_depth() || first) {
        state.set_output_queue_depth(out_load);
        prev_state.set_output_queue_depth(out_load);
        change = true;
    }

    if (change)
        BGPRouterInfo::Send(state);

    if (first) first = false;

    node_info_log_timer->Cancel();
    node_info_log_timer->Start(60*1000, boost::bind(&ControlNodeInfoLogTimer),
                               NULL);
    return true;
}

// Trigger graceful shutdown of control-node process.
//
// IO (evm) is shutdown first. Afterwards, main() resumes, shutting down rest of the
// objects, and eventually exit()s.
void ControlNodeShutdown() {
    static bool shutdown_;

    if (shutdown_) return;
    shutdown_ = true;

    // Shutdown event manager first to stop all IO activities.
    evm.Shutdown();
}

// Read command line options from a file for ease of use. These options read
// from file are appended to those specified in the command line.
int ReadCommandLineOptionsFromFile(int argc, char **argv,
                                   std::vector<string> &tokens, string &line,
                                   char **p_argv, size_t p_argv_size) {
    int p_argc = argc;

    // Copy command line options
    for (int i = 0; i < argc; i++) {
        p_argv[i] = argv[i];
    }

    for (int j = 0; j < argc; j++) {

        // Check for --options-file option
        if (!boost::iequals("--options-file", argv[j])) continue;

        // Make sure there is a file name specified.
        if ((j + 1) >= argc) break;

        // Read text from the file and split into different tokens.
        line = FileRead(argv[j + 1]);
        boost::split(tokens, line, boost::is_any_of(" \n\t"));
        for (size_t k = 0; k < tokens.size(); k++) {

            // Ignore empty strings.
            if (tokens[k].empty()) continue;

            // Make sure that there is enough room in the output vector.
            assert((size_t) p_argc < p_argv_size);

            // Retrieve char * token into output vector.
            p_argv[p_argc++] = const_cast<char *>(tokens[k].c_str());
        }
        break;
    }

    // Return the updated number of command line options to use.
    return p_argc;
}

int main(int argc, char *argv[]) {
    bool enable_local_logging = false;
    bool disable_logging = false;
    error_code error;
    string hostname(host_name(error));
    const string default_log_file = "<stdout>";
    const unsigned long default_log_file_size = 10*1024*1024; // 10MB
    const unsigned int default_log_file_index = 10;
    opt::options_description desc("Command line options");
    desc.add_options()
        ("bgp-port",
         opt::value<int>()->default_value(BgpConfigManager::kDefaultPort),
         "BGP listener port")
        ("collector", opt::value<string>(),
            "IP address of sandesh collector")
        ("collector-port", opt::value<int>(),
            "Port of sandesh collector")
        ("config-file", opt::value<string>()->default_value("bgp_config.xml"),
            "Configuration file")
        ("discovery-server", opt::value<string>(),
            "IP address of Discovery Server")
        ("discovery-port",
            opt::value<int>()->default_value(ContrailPorts::DiscoveryServerPort),
            "Port of Discovery Server")
        ("help", "help message")
        ("hostname", opt::value<string>()->default_value(hostname),
            "Hostname of control-node")
        ("host-ip", opt::value<string>(), "IP address of control-node")
        ("http-server-port",
            opt::value<int>()->default_value(ContrailPorts::HttpPortControl),
            "Sandesh HTTP listener port")
        ("log-category", opt::value<string>()->default_value(""),
            "Category filter for local logging of sandesh messages")
        ("log-disable", opt::bool_switch(&disable_logging),
             "Disable sandesh logging")
        ("log-file", opt::value<string>()->default_value(default_log_file),
             "Filename for the logs to be written to")
        ("log-file-index",
             opt::value<unsigned int>()->default_value(default_log_file_index),
             "Maximum log file roll over index")
        ("log-file-size",
             opt::value<unsigned long>()->default_value(default_log_file_size),
             "Maximum size of the log file")
        ("log-level", opt::value<string>()->default_value("SYS_NOTICE"),
            "Severity level for local logging of sandesh messages")
        ("log-local", opt::bool_switch(&enable_local_logging),
             "Enable local logging of sandesh messages")
        ("map-password", opt::value<string>(), "MAP server password")
        ("map-server-url", opt::value<string>(), "MAP server URL")
        ("map-user", opt::value<string>(), "MAP server username")
        ("options-file", opt::value<string>(), "Command line options file")
        ("use-certs", opt::value<string>(),
            "Certificates store to use for communication with MAP server")
        ("xmpp-port",
            opt::value<int>()->default_value(ContrailPorts::ControlXmpp),
            "XMPP listener port")
        ("version", "Display version information")
        ("use-certs", opt::value<string>(),
            "Use certificates to communicate with MAP server; Specify certificate store")
        ;

    std::vector<string> tokens;
    string line;
    char *p_argv[argc + 128];
    int p_argc;

    // Optionally, retrieve command line options from a file.
    p_argc = ReadCommandLineOptionsFromFile(argc, argv, tokens, line, p_argv,
                                            sizeof(p_argv)/sizeof(p_argv[0]));

    // Process collective options those specified in the command line and those
    // in the file (optionl).
    opt::variables_map var_map;
    opt::store(opt::parse_command_line(p_argc, p_argv, desc), var_map);
    opt::notify(var_map);

    if (var_map.count("help")) {
        cout << desc << endl;
        exit(0);
    }

    if (var_map.count("version")) {
        string build_info;
        ControlNodeVersion(build_info);
        cout << build_info << endl;
        exit(0);
    }

    ControlNode::SetProgramName(argv[0]);
    unsigned long log_file_size = default_log_file_size;
    unsigned long log_file_index = default_log_file_index;
    if (var_map.count("log-file-size")) {
        log_file_size = var_map["log-file-size"].as<unsigned long>();
    }
    if (var_map.count("log-file-index")) {
        log_file_index = var_map["log-file-index"].as<unsigned int>();
    }
    if (var_map["log-file"].as<string>() == default_log_file) {
        LoggingInit();
    } else {
        LoggingInit(var_map["log-file"].as<string>(), log_file_size,
                    log_file_index);
    }
    TaskScheduler::Initialize();
    ControlNode::SetDefaultSchedulingPolicy();
    BgpSandeshContext sandesh_context;

    if (!var_map.count("discovery-server")) {
        Sandesh::InitGenerator(
            g_vns_constants.ModuleNames.find(Module::CONTROL_NODE)->second,
            hostname, &evm,
            var_map["http-server-port"].as<int>(), &sandesh_context);
    }

    if (var_map.count("collector-port") && var_map.count("collector")) {
        int collector_port = var_map["collector-port"].as<int>();
        std::string collector_server = var_map["collector"].as<string>();
        Sandesh::ConnectToCollector(collector_server, collector_port);
    }
    Sandesh::SetLoggingParams(enable_local_logging,
                              var_map["log-category"].as<string>(),
                              var_map["log-level"].as<string>());

    //
    // XXX Disable logging -- for test purposes only
    //
    if (disable_logging) {
        SetLoggingDisabled(true);
    }

    boost::scoped_ptr<BgpServer> bgp_server(new BgpServer(&evm));
    sandesh_context.bgp_server = bgp_server.get();

    DB config_db;
    DBGraph config_graph;
    IFMapServer ifmap_server(&config_db, &config_graph, evm.io_service());
    sandesh_context.ifmap_server = &ifmap_server;
    IFMap_Initialize(&ifmap_server);

    bgp_server->config_manager()->Initialize(&config_db, &config_graph,
                                        var_map["hostname"].as<string>());
    ControlNode::SetHostname(var_map["hostname"].as<string>());
    BgpConfigParser parser(&config_db);
    parser.Parse(FileRead(var_map["config-file"].as<string>().c_str()));

    // TODO:  Initialize throws an exception (via boost) in case the
    // user does not have permissions to bind to the port.

    int bgp_port = var_map["bgp-port"].as<int>();

    LOG(DEBUG, "Starting Bgp Server at port " << bgp_port);
    bgp_server->session_manager()->Initialize(bgp_port);

    if (var_map.count("map-server-url")) {
        std::string certstore = var_map.count("use-certs") ?
                                var_map["use-certs"].as<string>() : string("");
        IFMapServerParser *parser = IFMapServerParser::GetInstance("vnc_cfg");
        IFMapManager *ifmapmgr = new IFMapManager(&ifmap_server,
                    var_map["map-server-url"].as<string>(),
                    var_map["map-user"].as<string>(),
                    var_map["map-password"].as<string>(),
                    certstore,
                    boost::bind(&IFMapServerParser::Receive, parser,
                                &config_db, _1, _2, _3), evm.io_service());
        ifmapmgr->Start();
        ifmap_server.set_ifmap_manager(ifmapmgr);
    }

    XmppServer *xmpp_server = new XmppServer(&evm, hostname);
    XmppInit init;
    XmppChannelConfig xmpp_cfg(false);
    xmpp_cfg.endpoint.port(var_map["xmpp-port"].as<int>());
    xmpp_cfg.FromAddr = XmppInit::kControlNodeJID;
    init.AddXmppChannelConfig(&xmpp_cfg);
    init.InitServer(xmpp_server, var_map["xmpp-port"].as<int>(), true);

    // Register XMPP channel peers
    boost::scoped_ptr<BgpXmppChannelManager> bgp_peer_manager(
                    new BgpXmppChannelManager(xmpp_server, bgp_server.get()));
    sandesh_context.xmpp_peer_manager = bgp_peer_manager.get();
    IFMapChannelManager ifmap_channel_mgr(xmpp_server, &ifmap_server);
    ifmap_server.set_ifmap_channel_manager(&ifmap_channel_mgr);

    //Register services with Discovery Service Server
    DiscoveryServiceClient *ds_client = NULL;
    if (var_map.count("discovery-server")) {
        tcp::endpoint dss_ep;
        dss_ep.address(address::from_string(var_map["discovery-server"].as<string>(),
                       error));
        dss_ep.port(var_map["discovery-port"].as<int>());
        ds_client = new DiscoveryServiceClient(&evm, dss_ep);
        ds_client->Init();

        // publish xmpp-server service
        std::string self_ip;
        if (var_map.count("host-ip")) {
            self_ip = var_map["host-ip"].as<string>();
        } else {
            tcp::resolver resolver(*evm.io_service());
            tcp::resolver::query query(boost::asio::ip::host_name(), "");
            tcp::resolver::iterator iter = resolver.resolve(query);
            self_ip = iter->endpoint().address().to_string();
        }
        ControlNode::SetSelfIp(self_ip);

        if (!self_ip.empty()) {
            stringstream pub_ss;
            pub_ss << "<xmpp-server><ip-address>" << self_ip <<
                      "</ip-address><port>" << var_map["xmpp-port"].as<int>() <<
                      "</port></xmpp-server>";
            std::string pub_msg;
            pub_msg = pub_ss.str();
            ds_client->Publish(DiscoveryServiceClient::XmppService, pub_msg);
        }

        //subscribe to collector service if not configured
        if (!var_map.count("collector")) {
            string subscriber_name = g_vns_constants.ModuleNames.find(Module::CONTROL_NODE)->second;

            Sandesh::CollectorSubFn csf = 0;
            csf = boost::bind(&DiscoveryServiceClient::Subscribe, ds_client, subscriber_name, _1, _2, _3);
            vector<string> list;
            list.clear();
            Sandesh::InitGenerator(subscriber_name,
                                   hostname, &evm,
                                   var_map["http-server-port"].as<int>(),
                                   csf,
                                   list,
                                   &sandesh_context);
        }
    }

    CpuLoadData::Init();
    start_time = UTCTimestampUsec();
    node_info_trigger =
        new TaskTrigger(boost::bind(&ControlNodeInfoLogger, sandesh_context),
            TaskScheduler::GetInstance()->GetTaskId("bgp::Config"), 0);

    node_info_log_timer = TimerManager::CreateTimer(*evm.io_service(),
        "ControlNode Info log timer");
    node_info_log_timer->Start(60*1000, boost::bind(&ControlNodeInfoLogTimer),
                               NULL);
    evm.Run();
    ShutdownServers(&bgp_peer_manager, ds_client);

    init.Reset();
    return 0;
}

ext: cc

max_stars_repo_name: sysbot/contrail-controller

max_issues_repo_name: sysbot/contrail-controller

max_forks_repo_name: sysbot/contrail-controller


text: #include <boost/functional/lightweight_forward_adapter.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <streambuf>
#include <string>
#include <thread>
#include <vector>
using namespace std;

#include "log.hpp"

#include "ctrlclaw.hpp"
#include "ostrichword.hpp"
#include "ipfspump.hpp"

static string longTxt(
    u8"它是由从地方到全球范围内几百万个私人的、学术界的、"
    u8"企业的和政府的网络所构成，通过电子，"
    u8"企业的和政府的网络所构成，通过<>"
    u8"无线和光纤网络技术等等<>一系列广泛的技术联系在一起。"
    u8"这种将计算机网络互相联接在一起的方法可称作“网络互联”，"
    u8"在这基础上发展出覆盖全世界的全球性互联网络称互联网，"
    u8"即是互相连接一起的网络。");

static string shortTxt(
    u8"人造卫星能够成功执行预定任务，单凭卫星本身是不行的，"
    u8"而需要完整的卫星工程系统");

/*
int main(int ac,char*av[])
{
  OstrichWord ostrich("./db/baidu.baike");
  auto learnOstrich = [&](const vector<string> &words) {
    ostrich.learn(words);
  };
  auto dumpOstrich = [&](const string &sentence,const vector<string> &words) {
    DUMP_VAR(sentence);
    for(auto word:words) {
      DUMP_VAR(word);
    }
  };
  CtrlClaw claw;
  claw.claw(longTxt);
  claw.eachSentence(dumpOstrich);
  claw.eachMultiByte(learnOstrich);
  ostrich.mergeWordByArticle();

  claw.claw(shortTxt);
  claw.eachMultiByte(learnOstrich);
  ostrich.mergeWordByArticle();
  return 0;
}
*/

#include <boost/foreach.hpp>
#include <boost/optional.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
namespace pt = boost::property_tree;

int main(int ac, char *av[]) {
  OstrichWord ostrich;
  auto learnOstrich = [&](const vector<string> &words) {
    ostrich.learn(words);
  };
  CtrlClaw claw;
  auto clawText = [&](const json &task, string &content,string &ws) {
    TRACE_VAR(task);
    claw.claw(content);
    claw.eachMultiByte(learnOstrich);
    ostrich.commitArticleIpfs(task,ws);
  };
  IpfsTextPump txtPump;
  txtPump.eachText(clawText);
  return 0;
}

ext: cpp


text:
// Andrew Naplavkov

#ifndef BARK_GEOMETRY_GEOMETRY_HPP
#define BARK_GEOMETRY_GEOMETRY_HPP

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <boost/geometry/multi/geometries/multi_linestring.hpp>
#include <boost/geometry/multi/geometries/multi_point.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
#include <boost/variant.hpp>
#include <vector>

namespace bark::geometry {

using point = boost::geometry::model::d2::point_xy<double>;
using linestring = boost::geometry::model::linestring<point>;
using polygon = boost::geometry::model::polygon<point, false, true>;
using multi_point = boost::geometry::model::multi_point<point>;
using multi_linestring = boost::geometry::model::multi_linestring<linestring>;
using multi_polygon = boost::geometry::model::multi_polygon<polygon>;
struct geometry_collection;

using geometry = boost::variant<point,
                                linestring,
                                polygon,
                                multi_point,
                                multi_linestring,
                                multi_polygon,
                                boost::recursive_wrapper<geometry_collection>>;

struct geometry_collection : std::vector<geometry> {
};

using box = boost::geometry::model::box<point>;

using multi_box = std::vector<box>;

using box_rtree =
    boost::geometry::index::rtree<box, boost::geometry::index::quadratic<16>>;

}  // namespace bark::geometry

#endif  // BARK_GEOMETRY_GEOMETRY_HPP

max_stars_repo_name: storm-ptr/bark

max_issues_repo_name: storm-ptr/bark

max_forks_repo_name: storm-ptr/bark


text:
/*=============================================================================
    Copyright (c) 2016 Kohei Takahashi

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/

#include <boost/detail/lightweight_test.hpp>
#include <boost/fusion/container.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/fusion/sequence/io/out.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/adapted/struct/define_assoc_struct.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/static_assert.hpp>
#include <iostream>

BOOST_FUSION_DEFINE_ASSOC_STRUCT(BOOST_PP_EMPTY(), empty_struct, )

int
main()
{
    using namespace boost;
    using namespace boost::fusion;

    std::cout << tuple_open('[');
    std::cout << tuple_close(']');
    std::cout << tuple_delimiter(", ");

    {
        BOOST_MPL_ASSERT_NOT((traits::is_view<empty_struct>));
        empty_struct e;

        std::cout << e << std::endl;
        BOOST_TEST(e == make_vector());

        BOOST_STATIC_ASSERT(fusion::result_of::size<empty_struct>::value == 0);
        BOOST_STATIC_ASSERT(fusion::result_of::empty<empty_struct>::value);
    }

    {
        vector<> v;
        empty_struct e;
        BOOST_TEST(v == e);
        BOOST_TEST_NOT(v != e);
        BOOST_TEST_NOT(v < e);
        BOOST_TEST(v <= e);
        BOOST_TEST_NOT(v > e);
        BOOST_TEST(v >= e);
    }

    {
        empty_struct e;

        // conversion from empty_struct to vector
        vector<> v(e);
        v = e;

        // conversion from empty_struct to list
        //list<> l(e);
        //l = e;
    }

    { // begin/end
        typedef fusion::result_of::begin<empty_struct>::type b;
        typedef fusion::result_of::end<empty_struct>::type e;

        BOOST_MPL_ASSERT((fusion::result_of::equal_to<b, e>));
    }

    BOOST_MPL_ASSERT((mpl::is_sequence<empty_struct>));
    BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_struct, void>));
    BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_struct, int>));

    return boost::report_errors();
}


text:
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2018 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.

#ifndef GRAPH_BLOCKMODEL_MULTIFLIP_MCMC_HH
#define GRAPH_BLOCKMODEL_MULTIFLIP_MCMC_HH

#include "config.h"

#include <vector>
#include <algorithm>

#include "graph_tool.hh"
#include "../support/graph_state.hh"
#include "graph_blockmodel_util.hh"
#include <boost/mpl/vector.hpp>

namespace graph_tool
{
using namespace boost;
using namespace std;

#define MCMC_BLOCK_STATE_params(State)                                         \
    ((__class__,&, mpl::vector<python::object>, 1))                            \
    ((state, &, State&, 0))                                                    \
    ((E,, size_t, 0))                                                          \
    ((beta,, double, 0))                                                       \
    ((c,, double, 0))                                                          \
    ((d,, double, 0))                                                          \
    ((a1,, double, 0))                                                         \
    ((an,, double, 0))                                                         \
    ((entropy_args,, entropy_args_t, 0))                                       \
    ((mproposals, & ,std::vector<size_t>&, 0))                                 \
    ((maccept, & ,std::vector<size_t>&, 0))                                    \
    ((allow_vacate,, bool, 0))                                                 \
    ((verbose,, bool, 0))                                                      \
    ((niter,, size_t, 0))

template <class State>
struct MCMC
{
    GEN_STATE_BASE(MCMCBlockStateBase, MCMC_BLOCK_STATE_params(State))

    template <class... Ts>
    class MCMCBlockState
        : public MCMCBlockStateBase<Ts...>
    {
    public:
        GET_PARAMS_USING(MCMCBlockStateBase<Ts...>,
                         MCMC_BLOCK_STATE_params(State))
        GET_PARAMS_TYPEDEF(Ts, MCMC_BLOCK_STATE_params(State))

        template <class... ATs,
                  typename std::enable_if_t<sizeof...(ATs) ==
                                            sizeof...(Ts)>* = nullptr>
        MCMCBlockState(ATs&&... as)
           : MCMCBlockStateBase<Ts...>(as...),
            _g(_state._g),
            _groups(num_vertices(_state._bg)),
            _vpos(get(vertex_index_t(), _state._g),
                  num_vertices(_state._g)),
            _rpos(get(vertex_index_t(), _state._bg),
                  num_vertices(_state._bg))
        {
            _state.init_mcmc(_c,
                             (_entropy_args.partition_dl ||
                              _entropy_args.degree_dl ||
                              _entropy_args.edges_dl));
            for (auto v : vertices_range(_state._g))
            {
                if (_state._vweight[v] > 0)
                    add_element(_groups[_state._b[v]], _vpos, v);
                _N++;
            }

            for (auto r : vertices_range(_state._bg))
            {
                if (_state._wr[r] > 0)
                    add_element(_vlist, _rpos, r);
            }
        }

        typename state_t::g_t& _g;

        std::vector<std::vector<size_t>> _groups;
        typename vprop_map_t<size_t>::type::unchecked_t _vpos;
        typename vprop_map_t<size_t>::type::unchecked_t _rpos;

        std::vector<size_t> _vlist;
        std::vector<size_t> _vs;

        size_t _null_move = null_group;

        size_t _nproposals = 0;
        size_t _N = 0;

        size_t node_state(size_t r)
        {
            return r;
        }

        bool skip_node(size_t r)
        {
            return _groups[r].empty();
        }

        size_t node_weight(size_t)
        {
            return _vs.size();
        }

        template <class RNG>
        size_t sample_m(size_t n, RNG& rng)
        {
            if (n == 1)
                return 1;

            std::bernoulli_distribution single(_a1);
            if (single(rng))
                return 1;

            if (n == 2)
                return 2;

            std::bernoulli_distribution merge(_an);
            if (merge(rng))
                return n;

            std::uniform_int_distribution<size_t> split(2, n - 1);
            return split(rng);
        }

        double log_pm(size_t m, size_t n)
        {
            if (n == 1)
                return 0;
            if (m == 1)
                return log(_a1);
            if (m == n)
            {
                if (n == 2)
                    return log1p(-_a1);
                return log1p(-_a1) + log(_an);
            }
            return log1p(-_a1) + log1p(-_an) - log(n-2);
        }

        template <class RNG>
        size_t move_proposal(size_t r, RNG& rng)
        {
            size_t m = sample_m(_groups[r].size(), rng);

            if (!_allow_vacate && _groups[r].size() == m)
                return null_group;

            assert(m <= _groups[r].size());

            _nproposals += m;
            _vs.clear();

            while (_vs.size() < m)
            {
                size_t v = uniform_sample(_groups[r], rng);
                _vs.push_back(v);
                remove_element(_groups[r], _vpos, v);
            }

            for (auto v : _vs)
                add_element(_groups[r], _vpos, v);

            size_t v = uniform_sample(_vs, rng);
            size_t s = _state.sample_block(v, _c, _d, rng);

            if (s >= _groups.size())
            {
                _groups.resize(s + 1);
                _rpos.resize(s + 1);
            }

            if (!_state.allow_move(r, s) || s == r)
                return null_group;

            if (!_groups[s].empty() || _groups[r].size() > m)
                _mproposals[m]++;
            return s;
        }

        std::tuple<double, double>
        virtual_move_dS(size_t r, size_t nr)
        {
            double dS = 0, a = 0;
            size_t m = _vs.size();

            a -= log_pm(m, _groups[r].size());
            a += log_pm(m, _groups[nr].size() + m);
            a -= -lbinom(_groups[r].size(), m);
            a += -lbinom(_groups[nr].size() + m, m);

            int B = _vlist.size();
            a -= -log(B);
            if (_groups[r].size() == m)
                B--;
            if (_groups[nr].empty())
                B++;
            a += -log(B);

            if (m == 1)
            {
                auto v = _vs.front();
                dS = _state.virtual_move(v, r, nr, _entropy_args);
                double pf = _state.get_move_prob(v, r, nr, _c, _d, false);
                double pb = _state.get_move_prob(v, nr, r, _c, _d, true);
                a += log(pb) - log(pf);
            }
            else
            {
                _state._egroups_enabled = false;
                double pf = 0, pb = 0;
                for (auto v : _vs)
                    pf += _state.get_move_prob(v, r, nr, _c, _d, false);
                pf /= m;
                for (auto v : _vs)
                {
                    dS += _state.virtual_move(v, r, nr, _entropy_args);
                    _state.move_vertex(v, nr);
                }
                for (auto v : _vs)
                    pb += _state.get_move_prob(v, nr, r, _c, _d, false);
                pb /= m;
                a += log(pb) - log(pf);
                for (auto v : _vs)
                    _state.move_vertex(v, r);
                _state._egroups_enabled = true;
            }
            return std::make_tuple(dS, a);
        }

        void perform_move(size_t r, size_t nr)
        {
            if (!_groups[nr].empty() || _groups[r].size() > _vs.size())
                _maccept[_vs.size()]++;
            if (_state._wr[nr] == 0)
                add_element(_vlist, _rpos, nr);
            for (auto v : _vs)
            {
                _state.move_vertex(v, nr);
                remove_element(_groups[r], _vpos, v);
                add_element(_groups[nr], _vpos, v);
            }
            if (_state._wr[r] == 0)
                remove_element(_vlist, _rpos, r);
        }

        bool is_deterministic()
        {
            return false;
        }

        bool is_sequential()
        {
            return false;
        }

        auto& get_vlist()
        {
            return _vlist;
        }

        double get_beta()
        {
            return _beta;
        }

        size_t get_niter()
        {
            if (_nproposals < _niter * _N)
                return std::numeric_limits<size_t>::max();
            return 0;
        }

        void step(size_t, size_t)
        {
        }
    };
};

} // graph_tool namespace

#endif //GRAPH_BLOCKMODEL_MCMC_HH

ext: hh


text:
// Software License for MTL
//
// Copyright (c) 2007 The Trustees of Indiana University.
//               2008 Dresden University of Technology and the Trustees of Indiana University.
//               2010 SimuNova UG (haftungsbeschränkt), www.simunova.com.
// All rights reserved.
// Authors: Peter Gottschling and Andrew Lumsdaine
//
// This file is part of the Matrix Template Library
//
// See also license.mtl.txt in the distribution.

#include <iostream>
#include <cmath>
#include <complex>
#include <boost/numeric/mtl/concept/collection.hpp>
#include <boost/numeric/mtl/matrix/compressed2D.hpp>
#include <boost/numeric/mtl/matrix/dense2D.hpp>
#include <boost/numeric/mtl/matrix/laplacian_setup.hpp>
#include <boost/numeric/mtl/vector/dense_vector.hpp>
#include <boost/numeric/mtl/operation/print.hpp>
#include <boost/numeric/mtl/operation/operators.hpp>

using namespace std;

template <typename MatrixA>
void test(MatrixA& A, unsigned dim1, unsigned dim2, const char* name)
{
    const unsigned max_print_size= 25;
    cout << "\n" << name << "\n";
    laplacian_setup(A, dim1, dim2);

    unsigned size= dim1 * dim2;
    mtl::dense_vector<double> v(size);
    for (unsigned i= 0; i < num_cols(A); i++)
	v[i]= A[12][i];

    // Resulting vector has same value type as matrix
    typedef typename mtl::Collection<MatrixA>::value_type rvalue_type;
    mtl::dense_vector<rvalue_type> w(size), w2;

    w= A * v;
    //mult(A, v, w);

    if (size <= max_print_size)
	cout << "A= \n" << A << "\n\nv= " << v << "\n\nA*v= " << w << "\n";

    // Same test as in matrix product: resulting vector corresponds to column 12
    // Check for stencil below in the middle of the matrix
    //        1
    //     2 -8  2
    //  1 -8 20 -8  1
    //     2 -8  2
    //        1
    if (dim1 == 5 && dim2 == 5) {
	rvalue_type twenty(20.0), two(2.0), one(1.0), zero(0.0), minus_eight(-8.0);
	MTL_THROW_IF(w[12] != twenty, mtl::runtime_error("wrong diagonal"));
	MTL_THROW_IF(w[13] != minus_eight, mtl::runtime_error("wrong east neighbor"));
	MTL_THROW_IF(w[14] != one, mtl::runtime_error("wrong east east neighbor"));
	MTL_THROW_IF(w[15] != zero, mtl::runtime_error("wrong zero-element"));
	MTL_THROW_IF(w[17] != minus_eight, mtl::runtime_error("wrong south neighbor"));
	MTL_THROW_IF(w[18] != two, mtl::runtime_error("wrong south east neighbor"));
	MTL_THROW_IF(w[22] != one, mtl::runtime_error("wrong south south neighbor"));
    }

    w+= A * v;

    if (size <= max_print_size)
	cout << "w+= A*v= \n\n" << w << "\n";

    // Check for stencil, must be doubled now
    if (dim1 == 5 && dim2 == 5) {
	rvalue_type forty(40.0), four(4.0);
	MTL_THROW_IF(w[12] != forty, mtl::runtime_error("wrong diagonal"));
	MTL_THROW_IF(w[18] != four, mtl::runtime_error("wrong south east neighbor"));
    }

    w-= A * v;

    if (size <= max_print_size)
	cout << "w-= A*v= \n\n" << w << "\n";

    // Check for stencil, must be A*v now
    if (dim1 == 5 && dim2 == 5) {
	rvalue_type twenty(20.0), two(2.0);
	MTL_THROW_IF(w[12] != twenty, mtl::runtime_error("wrong diagonal"));
	MTL_THROW_IF(w[18] != two, mtl::runtime_error("wrong south east neighbor"));
    }

#if 0
    rvalue_type dotexp= dot(w, v), dotres;
    mtl::with_dot(w2, dotres)= A * v;

    w2-= w;
    if (two_norm(w2) > 0.001)
	throw "Vector result wrong in with_dot computation.";
    if (std::abs(dotres - dotexp) > 0.001)
	throw "Dot result wrong in with_dot computation.";
#endif
}

int main(int argc, char* argv[])
{
    using namespace mtl;

    unsigned dim1= 5, dim2= 5;

    if (argc > 2) {dim1= atoi(argv[1]); dim2= atoi(argv[2]);}
    unsigned size= dim1 * dim2;

    compressed2D<double>                                 cr(size, size);
    compressed2D<double, mat::parameters<col_major> > cc(size, size);

    dense2D<double>                                      dr(size, size);
    dense2D<double, mat::parameters<col_major> >      dc(size, size);

    test(cr, dim1, dim2, "Row-major sparse");
#if 1
    test(cc, dim1, dim2, "Column-major sparse");

    test(dr, dim1, dim2, "Row-major dense");
    test(dc, dim1, dim2, "Column-major dense");
#endif
    return 0;
}


text:
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE libmace
#include <boost/test/unit_test.hpp>

#include "mvector.h"
#include "MaceKey.h"
#include "Util.h"
#include "ContextMapping.h"
#include "params.h"
using namespace boost::unit_test;

BOOST_AUTO_TEST_CASE(TestVector)
{
  mace::vector<int> v;
  v.push_back(1);
  v.push_back(2);
  BOOST_REQUIRE_EQUAL(v.size(), (size_t)2);

  std::string s = v.serializeStr();
  std::string t = s;

  mace::vector<int> w;
  w.deserializeStr(t);

  BOOST_REQUIRE_EQUAL(v.toString(), w.toString());
  BOOST_REQUIRE(v == w);
}

BOOST_AUTO_TEST_SUITE( TestMaceKey )
BOOST_AUTO_TEST_CASE(BasicMaceKeyTest)
{
  Log::disableDefaultWarning();
  params::set("MACE_ADDRESS_ALLOW_LOOPBACK", "1");
  mace::MaceKey j = mace::MaceKey(mace::ipv4, "23.24.25.26");
  BOOST_REQUIRE(! j.isNullAddress());

  BOOST_TEST_CHECKPOINT("The following tests if DNS is working in Mace");
  mace::MaceKey k = mace::MaceKey(mace::ipv4, "www.google.com");
  BOOST_WARN(! k.isNullAddress());

  BOOST_TEST_CHECKPOINT("Now testing serialization of MaceKey");
  mace::MaceKey l = mace::MaceKey(mace::ipv4, "127.0.0.1:1024");
  std::string l_s = l.serializeStr();
  uint8_t expected_s[] = {1 /* IPV4 */, 127, 0, 0, 1, 4, 0, 255, 255, 255, 255, 0, 0};
  for (size_t i = 0; i < sizeof(expected_s); i++) {
    BOOST_REQUIRE_EQUAL( static_cast<uint8_t>(l_s[i]), expected_s[i]);
  }
}
BOOST_AUTO_TEST_CASE(MaceKey_vnode)
{
  mace::MaceAddr addr1 = Util::getMaceAddr("cloud01.cs.purdue.edu:5000");
  mace::MaceAddr addr2 = Util::getMaceAddr("cloud02.cs.purdue.edu:6000");
  mace::MaceAddr addr3 = Util::getMaceAddr("cloud03.cs.purdue.edu:7000");
  mace::ContextMapping::updateVirtualNodes( 1, addr1 );
  mace::ContextMapping::updateVirtualNodes( 2, addr2 );
  mace::ContextMapping::updateVirtualNodes( 3, addr3 );

  mace::MaceKey vnode1( mace::vnode, 1 );
  mace::MaceKey vnode2( mace::vnode, 2 );
  mace::MaceKey vnode3( mace::vnode, 3 );

  BOOST_REQUIRE(! vnode1.isNullAddress());
  BOOST_REQUIRE(! vnode2.isNullAddress());
  BOOST_REQUIRE(! vnode3.isNullAddress());

  BOOST_REQUIRE( vnode1.getMaceAddr() == addr1 );
  BOOST_REQUIRE( vnode2.getMaceAddr() == addr2 );
  BOOST_REQUIRE( vnode3.getMaceAddr() == addr3 );

  BOOST_REQUIRE( vnode1.getMaceAddr() != addr2 );
  BOOST_REQUIRE( vnode1.getMaceAddr() != addr3 );

  BOOST_REQUIRE( vnode2.getMaceAddr() != addr1 );
  BOOST_REQUIRE( vnode2.getMaceAddr() != addr3 );

  BOOST_REQUIRE( vnode3.getMaceAddr() != addr1 );
  BOOST_REQUIRE( vnode3.getMaceAddr() != addr2 );

  mace::MaceAddr addr4 = Util::getMaceAddr("cloud04.cs.purdue.edu:8000");
  mace::ContextMapping::updateVirtualNodes( 1, addr4 );
  BOOST_REQUIRE(! vnode1.isNullAddress());
  BOOST_REQUIRE( vnode1.getMaceAddr() != addr1 );
  BOOST_REQUIRE( vnode1.getMaceAddr() == addr4 );

  mace::string s;
  mace::serialize( s, &vnode1 );
  mace::MaceKey k;
  mace::deserialize( s, &k );
  BOOST_REQUIRE( k == vnode1 );
}
BOOST_AUTO_TEST_CASE(MaceKey_ctxnode)
{
  mace::MaceAddr addr1 = Util::getMaceAddr("cloud01.cs.purdue.edu:5000");
  mace::MaceAddr addr2 = Util::getMaceAddr("cloud02.cs.purdue.edu:6000");
  mace::MaceAddr addr3 = Util::getMaceAddr("cloud03.cs.purdue.edu:7000");

  mace::MaceKey node1( mace::ctxnode, addr1 );
  mace::MaceKey node2( mace::ctxnode, addr2 );
  mace::MaceKey node3( mace::ctxnode, addr3 );

  BOOST_REQUIRE(! node1.isNullAddress());
  BOOST_REQUIRE(! node2.isNullAddress());
  BOOST_REQUIRE(! node3.isNullAddress());

  BOOST_REQUIRE( node1.getMaceAddr() == addr1 );
  BOOST_REQUIRE( node2.getMaceAddr() == addr2 );
  BOOST_REQUIRE( node3.getMaceAddr() == addr3 );

  BOOST_REQUIRE( node1.getMaceAddr() != addr2 );
  BOOST_REQUIRE( node1.getMaceAddr() != addr3 );

  BOOST_REQUIRE( node2.getMaceAddr() != addr1 );
  BOOST_REQUIRE( node2.getMaceAddr() != addr3 );

  BOOST_REQUIRE( node3.getMaceAddr() != addr1 );
  BOOST_REQUIRE( node3.getMaceAddr() != addr2 );

  mace::string s;
  mace::serialize( s, &node1 );
  mace::MaceKey k;
  mace::deserialize( s, &k );
  BOOST_REQUIRE( k == node1 );
}
BOOST_AUTO_TEST_SUITE_END()
#include <iostream>
BOOST_AUTO_TEST_SUITE( s1 )
BOOST_AUTO_TEST_CASE(XTest)
{
    //std::cout<< boost::unit_test::framework::master_test_suite().argc << std::endl;
    int x = 1;
    BOOST_TEST_MESSAGE("message");
    BOOST_WARN( x == 2 );
    //BOOST_TEST_CHECKPOINT("The following tests if DNS is working in Mace");
    //BOOST_REQUIRE_EQUAL( x , 2 );

}
BOOST_AUTO_TEST_SUITE_END()

/*test_suite*
init_unit_test_suite( int argc, char* argv[] )
{
    framework::master_test_suite().p_name.value = "my master test suite name";

    return 0;
}*/

max_stars_repo_name: jojochuang/eventwave

max_issues_repo_name: jojochuang/eventwave

max_forks_repo_name: jojochuang/eventwave


text:
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "script/standard.h"

#include "pubkey.h"
#include "script/script.h"
#include "util.h"
#include "utilstrencodings.h"
#include "crypto/common.h"
#include "validation.h"

#include <boost/foreach.hpp>

using namespace std;

typedef vector<unsigned char> valtype;

bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER;
unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
bool fAcceptRegisteraddress = DEFAULT_ACCEPT_REGISTERADDRESS;
unsigned nMaxRegisteraddressBytes = MAX_OP_REGISTERADDRESS_RELAY;

CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}

const char* GetTxnOutputType(txnouttype t)
{
    switch (t)
    {
    case TX_NONSTANDARD: return "nonstandard";
    case TX_PUBKEY: return "pubkey";
    case TX_PUBKEYHASH: return "pubkeyhash";
    case TX_SCRIPTHASH: return "scripthash";
    case TX_MULTISIG: return "multisig";
    case TX_NULL_DATA: return "nulldata";
    case TX_REGISTERADDRESS_V0: return "registeraddress_v0";
    case TX_DEREGISTERADDRESS_V0: return "deregisteraddress_v0";
    case TX_REGISTERADDRESS_V1: return "registeraddress_v1";
    case TX_DEREGISTERADDRESS_V1: return "deregisteraddress_v1";
    case TX_WITNESS_V0_KEYHASH: return "witness_v0_keyhash";
    case TX_WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash";
    case TX_TRUE: return "true";
    case TX_FEE: return "fee";
    case TX_LOCKED_MULTISIG: return "lockedmultisig";
    }
    return NULL;
}

/** Check push data opcode is between 1 and 5 bytes for OP_CHECKLOCKTIMEVERIFY argument */
static constexpr bool IsCheckLockTimeSize(opcodetype opcode)
{
    return opcode >=1 && opcode <= 5;
}

static bool MatchLocked(const CScript& script, valtype& locktime)
{
    opcodetype opcode1;
    vector<unsigned char> vch1;
    CScript::const_iterator pc1 = script.begin();

    // Attempt to parse locktime parameter of OP_CHECKLOCKTIMEVERIFY
    if (!script.GetOp(pc1, opcode1, vch1))
        return false;
    if (IsCheckLockTimeSize(opcode1)
            && script.size() >= (size_t)(3 + opcode1)
            && script[1 + opcode1] == OP_CHECKLOCKTIMEVERIFY
            && script[2 + opcode1] == OP_DROP) {
        const CScriptNum nLockTime(vch1, true, 5);
        locktime = nLockTime.getvch();
        return true;
    }
    return false;
}

static bool MatchPayToPubkey(const CScript& script, valtype& pubkey)
{
    if (script.size() == CPubKey::PUBLIC_KEY_SIZE + 2 && script[0] == CPubKey::PUBLIC_KEY_SIZE && script.back() == OP_CHECKSIG) {
        pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::PUBLIC_KEY_SIZE + 1);
        return CPubKey::ValidSize(pubkey);
    }
    if (script.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE + 2 && script[0] == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE && script.back() == OP_CHECKSIG) {
        pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::COMPRESSED_PUBLIC_KEY_SIZE + 1);
        return CPubKey::ValidSize(pubkey);
    }
    return false;
}

static bool MatchPayToPubkeyHash(const CScript& script, valtype& pubkeyhash)
{
    if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG) {
        pubkeyhash = valtype(script.begin () + 3, script.begin() + 23);
        return true;
    }
    return false;
}

/** Test for "small positive integer" script opcodes - OP_1 through OP_16. */
static constexpr bool IsSmallInteger(opcodetype opcode)
{
    return opcode >= OP_1 && opcode <= OP_16;
}

static bool MatchMultisig(const CScript& script, unsigned int& required, std::vector<valtype>& pubkeys)
{
    opcodetype opcode;
    valtype data;
    CScript::const_iterator it = script.begin();
    if (script.size() < 1 || script.back() != OP_CHECKMULTISIG) return false;

    if (!script.GetOp(it, opcode, data) || !IsSmallInteger(opcode)) return false;
    required = CScript::DecodeOP_N(opcode);
    while (script.GetOp(it, opcode, data) && CPubKey::ValidSize(data)) {
        pubkeys.emplace_back(std::move(data));
    }
    if (!IsSmallInteger(opcode)) return false;
    unsigned int keys = CScript::DecodeOP_N(opcode);
    if (pubkeys.size() != keys || keys < required) return false;
    return (it + 1 == script.end());
}

/**
 * Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
 */
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsigned char> >& vSolutionsRet)
{
    vSolutionsRet.clear();

    // Shortcut for pay-to-script-hash, which are more constrained than the other types:
    // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
    if (scriptPubKey.IsPayToScriptHash())
    {
        typeRet = TX_SCRIPTHASH;
        vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
        vSolutionsRet.push_back(hashBytes);
        return true;
    }

    if (scriptPubKey == CScript()) {
        typeRet = TX_FEE;
        return true;
    }

    int witnessversion;
    std::vector<unsigned char> witnessprogram;
    if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
        if (witnessversion == 0 && witnessprogram.size() == 20) {
            typeRet = TX_WITNESS_V0_KEYHASH;
            vSolutionsRet.push_back(witnessprogram);
            return true;
        }
        if (witnessversion == 0 && witnessprogram.size() == 32) {
            typeRet = TX_WITNESS_V0_SCRIPTHASH;
            vSolutionsRet.push_back(witnessprogram);
            return true;
        }
        return false;
    }

    //Register address transaction
    std::vector<unsigned char> radata;
    int raversion;
    bool rawhitelist;
    if(scriptPubKey.IsRegisteraddress(raversion, radata, rawhitelist)){
        if(raversion == 0){
            if(rawhitelist){
                typeRet = TX_REGISTERADDRESS_V0;
            } else {
                typeRet = TX_DEREGISTERADDRESS_V0;
            }
        } else if(raversion == 1){
            if(rawhitelist){
                typeRet = TX_REGISTERADDRESS_V1;
            } else {
                typeRet = TX_DEREGISTERADDRESS_V1;
            }
        }
        vSolutionsRet.push_back(radata);
        return true;
    }

    if (scriptPubKey == CScript() << OP_TRUE) {
        typeRet = TX_TRUE;
        return true;
    }

    // Provably prunable, data-carrying output
    //
    // So long as script passes the IsUnspendable() test and all but the first
    // byte passes the IsPushOnly() test we don't care what exactly is in the
    // script.
    if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
        typeRet = TX_NULL_DATA;
        return true;
    }

    std::vector<unsigned char> data;
    if (MatchPayToPubkey(scriptPubKey, data)) {
        typeRet = TX_PUBKEY;
        vSolutionsRet.push_back(std::move(data));
        return true;
    }

    if (MatchPayToPubkeyHash(scriptPubKey, data)) {
        typeRet = TX_PUBKEYHASH;
        vSolutionsRet.push_back(std::move(data));
        return true;
    }

    // Before checking for multisig, check if script is locked and if that is
    // the case skip the LOCKTIME OP_CHECKLOCKTIMEVERIFY OP_DROP of the script
    bool fIsLocked = false;
    CScript scriptPubKeyLocked;
    if (MatchLocked(scriptPubKey, data)) {
        fIsLocked = true;
        scriptPubKeyLocked = CScript(scriptPubKey.begin() + 3 + data.size(), scriptPubKey.end());
        vSolutionsRet.push_back(std::move(data)); // push lock time data
    }

    unsigned int required;
    std::vector<std::vector<unsigned char>> keys;
    if (MatchMultisig(fIsLocked ? scriptPubKeyLocked : scriptPubKey, required, keys)) {
        typeRet = fIsLocked ? TX_LOCKED_MULTISIG : TX_MULTISIG;
        vSolutionsRet.push_back({static_cast<unsigned char>(required)}); // safe as required is in range 1..16
        vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end());
        vSolutionsRet.push_back({static_cast<unsigned char>(keys.size())}); // safe as size is in range 1..16
        return true;
    }

    vSolutionsRet.clear();
    typeRet = TX_NONSTANDARD;
    return false;
}

bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
{
    vector<valtype> vSolutions;
    txnouttype whichType;
    if (!Solver(scriptPubKey, whichType, vSolutions))
        return false;

    if (whichType == TX_PUBKEY)
    {
        CPubKey pubKey(vSolutions[0]);
        if (!pubKey.IsValid())
            return false;

        addressRet = pubKey.GetID();
        return true;
    }
    else if (whichType == TX_PUBKEYHASH)
    {
        addressRet = CKeyID(uint160(vSolutions[0]));
        return true;
    }
    else if (whichType == TX_SCRIPTHASH)
    {
        addressRet = CScriptID(uint160(vSolutions[0]));
        return true;
    }
    // Multisig txns have more than one address...
    return false;
}

bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vector<CTxDestination>& addressRet, int& nRequiredRet)
{
    addressRet.clear();
    typeRet = TX_NONSTANDARD;
    vector<valtype> vSolutions;
    if (!Solver(scriptPubKey, typeRet, vSolutions))
        return false;
    if (typeRet == TX_NULL_DATA || typeRet == TX_FEE || typeRet == TX_REGISTERADDRESS_V0
        || typeRet == TX_DEREGISTERADDRESS_V0 || typeRet == TX_REGISTERADDRESS_V1
        || typeRet == TX_DEREGISTERADDRESS_V1){
        // This is data, not addresses
        return false;
    }

    if (typeRet == TX_MULTISIG)
    {
        nRequiredRet = vSolutions.front()[0];
        for (unsigned int i = 1; i < vSolutions.size()-1; i++)
        {
            CPubKey pubKey(vSolutions[i]);
            if (!pubKey.IsValid())
                continue;

            CTxDestination address = pubKey.GetID();
            addressRet.push_back(address);
        }

        if (addressRet.empty())
            return false;
    }
    else
    {
        nRequiredRet = 1;
        CTxDestination address;
        if (!ExtractDestination(scriptPubKey, address))
           return false;
        addressRet.push_back(address);
    }

    return true;
}

namespace
{
class CScriptVisitor : public boost::static_visitor<bool>
{
private:
    CScript *script;
public:
    CScriptVisitor(CScript *scriptin) { script = scriptin; }

    bool operator()(const CNoDestination &dest) const {
        script->clear();
        return false;
    }

    bool operator()(const CKeyID &keyID) const {
        script->clear();
        *script << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
        return true;
    }

    bool operator()(const CScriptID &scriptID) const {
        script->clear();
        *script << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
        return true;
    }
};
}

CScript GetScriptForDestination(const CTxDestination& dest)
{
    CScript script;

    boost::apply_visitor(CScriptVisitor(&script), dest);
    return script;
}

CScript GetScriptForRawPubKey(const CPubKey& pubKey)
{
    return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end()) << OP_CHECKSIG;
}

CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
{
    CScript script;

    script << CScript::EncodeOP_N(nRequired);
    BOOST_FOREACH(const CPubKey& key, keys)
        script << ToByteVector(key);
    script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
    return script;
}

CScript GetScriptForWitness(const CScript& redeemscript)
{
    CScript ret;

    txnouttype typ;
    std::vector<std::vector<unsigned char> > vSolutions;
    if (Solver(redeemscript, typ, vSolutions)) {
        if (typ == TX_PUBKEY) {
            unsigned char h160[20];
            CHash160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160);
            ret << OP_0 << std::vector<unsigned char>(&h160[0], &h160[20]);
            return ret;
        } else if (typ == TX_PUBKEYHASH) {
           ret << OP_0 << vSolutions[0];
           return ret;
        }
    }
    uint256 hash;
    CSHA256().Write(&redeemscript[0], redeemscript.size()).Finalize(hash.begin());
    ret << OP_0 << ToByteVector(hash);
    return ret;
}

max_stars_repo_name: commerceblock/elements

max_issues_repo_name: commerceblock/elements

max_forks_repo_name: commerceblock/elements


text:
#ifndef HANDLE_H
#define HANDLE_H

#include <boost/utility/string_ref.hpp>
#include <boost/unordered_map.hpp>
#include <boost/property_tree/ptree.hpp>
#include "JSONOutput.hpp"

namespace advpl_ls {
    class Handler {
    public:
      Handler(JSONOutput &Output) : Output(Output) {}
      virtual ~Handler() = default;

      /// Called when the server receives a method call. This is supposed to return
      /// a result on Outs. The default implementation returns an "unknown method"
      /// error to the client and logs a warning.
      virtual void handleMethod(boost::property_tree::ptree Params, std::string ID)
      {

      }
      /// Called when the server receives a notification. No result should be
      /// written to Outs. The default implemetation logs a warning.
      //virtual void handleNotification(llvm::yaml::MappingNode *Params);

    protected:
      JSONOutput &Output;

      /// Helper to write a JSONRPC result to Output.
      void writeMessage(const std::string &Message) {
          Output.writeMessage(Message);
         }
    };
}
#endif

max_stars_repo_name: advpl/advpl-language-server-cxx

max_issues_repo_name: ragssoftwares/advpl-language-server-cxx

max_forks_repo_name: ragssoftwares/advpl-language-server-cxx


text:
// Copyright (C) 2015 The Regents of the University of California (Regents).
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of The Regents or University of California nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Please contact the author of this library if you have any questions.
// Author: Chris Sweeney (cmsweeney@cs.ucsb.edu)

#include "theia/sfm/extract_maximally_parallel_rigid_subgraph.h"

#include <Eigen/Core>
#include <Eigen/LU>
#include <ceres/rotation.h>

#include <algorithm>
#include <unordered_map>
#include <vector>

#include "theia/sfm/pose/util.h"
#include "theia/sfm/types.h"
#include "theia/sfm/view_graph/view_graph.h"
#include "theia/util/map_util.h"

namespace theia {
namespace {

void FormAngleMeasurementMatrix(
    const std::unordered_map<ViewId, Eigen::Vector3d>& orientations,
    const ViewGraph& view_graph,
    const std::unordered_map<ViewId, int>& view_ids_to_index,
    Eigen::MatrixXd* angle_measurements) {
  const auto& view_pairs = view_graph.GetAllEdges();
  angle_measurements->setZero();

  // Set up the matrix such that t_{i,j} x (c_j - c_i) = 0.
  int i = 0;
  for (const auto& view_pair : view_pairs) {
    // Get t_{i,j} and rotate it such that it is oriented in the global
    // reference frame.
    Eigen::Matrix3d world_to_view1_rotation;
    ceres::AngleAxisToRotationMatrix(
        FindOrDie(orientations, view_pair.first.first).data(),
        ceres::ColumnMajorAdapter3x3(world_to_view1_rotation.data()));
    const Eigen::Vector3d rotated_translation =
        world_to_view1_rotation.transpose() * view_pair.second.position_2;
    const Eigen::Matrix3d cross_product_mat =
        CrossProductMatrix(rotated_translation);

    // Find the column locations of the two views.
    const int view1_col =
        3 * FindOrDie(view_ids_to_index, view_pair.first.first);
    const int view2_col =
        3 * FindOrDie(view_ids_to_index, view_pair.first.second);

    angle_measurements->block<3, 3>(3 * i, view1_col) = -cross_product_mat;
    angle_measurements->block<3, 3>(3 * i, view2_col) = cross_product_mat;
    ++i;
  }
}

// Computes the cosine distance in each dimension x, y, and z and returns the
// maximum cosine distance.
//
// cos distance = 1.0 - a.dot(b) / (norm(a) * norm(b))
double ComputeCosineDistance(const Eigen::MatrixXd& mat1,
                             const Eigen::MatrixXd& mat2) {
  Eigen::Vector3d cos_distance;
  for (int i = 0; i < 3; i++) {
    cos_distance(i) = 1.0 - std::abs(mat1.row(i).dot(mat2.row(i)));
  }
  return cos_distance.maxCoeff();
}

// Find the maximal rigid component containing fixed_node. This is done by
// examining which nodes are parallel when removing node fixed_node from the
// null space. The nodes are only parallel if they are part of the maximal rigid
// component with fixed_node.
void FindMaximalParallelRigidComponent(const Eigen::MatrixXd& null_space,
                                       const int fixed_node,
                                       std::unordered_set<int>* largest_cc) {
  static const double kMaxCosDistance = 1e-5;
  static const double kMaxNorm = 1e-10;

  const int num_nodes = null_space.rows() / 3;

  largest_cc->insert(fixed_node);

  const Eigen::MatrixXd fixed_null_space_component =
      null_space.block(3 * fixed_node, 0, 3, null_space.cols());

  // Remove the fixed node from the rest of the null space.
  Eigen::MatrixXd modified_null_space =
      null_space - fixed_null_space_component.replicate(num_nodes, 1);

  // Normalize all rows to be unit-norm. If the rows have a very small norm then
  // they are parallel to the fixed_node. and should be set to zero.
  const Eigen::VectorXd norms = modified_null_space.rowwise().norm();

  modified_null_space.rowwise().normalize();

  // Find the pairs to match. Add all indices that are close to 0-vectors, as
  // they are clearly part of the rigid component.
  std::vector<int> indices_to_match;
  for (int i = 0; i < num_nodes; i++) {
    // Skip this index if it is fixed.
    if (i == fixed_node) {
      continue;
    }

    // Skip this index if it is nearly a 0-vector because this means it is
    // clearly part of the rigid component.
    if (norms(3 * i) < kMaxNorm && norms(3 * i + 1) < kMaxNorm &&
        norms(3 * i + 2) < kMaxNorm) {
      largest_cc->insert(i);
      continue;
    }

    indices_to_match.emplace_back(i);
  }

  // Each node has three dimensions (x, y, z). We only compare parallel-ness
  // between similar dimensions. If all x, y, z dimensions are parallel then
  // the two nodes will be parallel.
  for (int i = 0; i < indices_to_match.size(); i++) {
    // Test all other nodes (that have not been tested) to determine if they are
    // parallel to this node.
    const Eigen::MatrixXd& block1 = modified_null_space.block(
        3 * indices_to_match[i], 0, 3, null_space.cols());

    for (int j = i + 1; j < indices_to_match.size(); j++) {
      const Eigen::MatrixXd& block2 = modified_null_space.block(
          3 * indices_to_match[j], 0, 3, null_space.cols());

      const double cos_distance = ComputeCosineDistance(block1, block2);
      if (cos_distance < kMaxCosDistance) {
        largest_cc->insert(indices_to_match[i]);
        largest_cc->insert(indices_to_match[j]);
      }
    }
  }
}

}  // namespace

void ExtractMaximallyParallelRigidSubgraph(
    const std::unordered_map<ViewId, Eigen::Vector3d>& orientations,
    ViewGraph* view_graph) {
  // Create a mapping of indexes to ViewIds for our linear system.
  std::unordered_map<ViewId, int> view_ids_to_index;
  view_ids_to_index.reserve(orientations.size());
  for (const auto& orientation : orientations) {
    if (!view_graph->HasView(orientation.first)) {
      continue;
    }
    const int current_index = view_ids_to_index.size();
    InsertIfNotPresent(&view_ids_to_index, orientation.first, current_index);
  }

  // Form the global angle measurements matrix from:
  //    t_{i,j} x (c_j - c_i) = 0.
  Eigen::MatrixXd angle_measurements(3 * view_graph->NumEdges(),
                                     3 * orientations.size());
  FormAngleMeasurementMatrix(
      orientations, *view_graph, view_ids_to_index, &angle_measurements);

  // Extract the null space of the angle measurements matrix.
  Eigen::FullPivLU<Eigen::MatrixXd> lu(angle_measurements.transpose() *
                                       angle_measurements);
  const Eigen::MatrixXd null_space = lu.kernel();

  // For each node in the graph (i.e. each camera), set the null space component
  // to be zero such that the camera position would be fixed at the origin. If
  // two nodes i and j are in the same rigid component, then their null spaces
  // will be parallel because the camera positions may only change by a
  // scale. We find all components that are parallel to find the rigid
  // components. The largest of such component is the maximally parallel rigid
  // component of the graph.
  std::unordered_set<int> maximal_rigid_component;
  for (int i = 0; i < orientations.size(); i++) {
    std::unordered_set<int> temp_cc;
    FindMaximalParallelRigidComponent(null_space, i, &temp_cc);
    if (temp_cc.size() > maximal_rigid_component.size()) {
      std::swap(temp_cc, maximal_rigid_component);
    }
  }

  // Only keep the nodes in the largest maximally parallel rigid component.
  for (const auto& orientation : orientations) {
    const int index = FindOrDie(view_ids_to_index, orientation.first);
    // If the view is not in the maximal rigid component then remove it from the
    // view graph.
    if (!ContainsKey(maximal_rigid_component, index) &&
        view_graph->HasView(orientation.first)) {
      CHECK(view_graph->RemoveView(orientation.first))
          << "Could not remove view id " << orientation.first
          << " from the view graph because it does not exist.";
    }
  }
}

}  // namespace theia

max_stars_repo_name: urbste/TheiaSfM

max_issues_repo_name: urbste/TheiaSfM

max_forks_repo_name: urbste/TheiaSfM


text:
// Copyright (c) 2014-2020 Daniel Kraft
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <base58.h>
#include <chainparams.h>
#include <core_io.h>
#include <init.h>
#include <key_io.h>
#include <names/common.h>
#include <names/main.h>
#include <primitives/transaction.h>
#include <rpc/names.h>
#include <rpc/server.h>
#include <script/names.h>
#include <txmempool.h>
#include <util/strencodings.h>
#include <validation.h>
#ifdef ENABLE_WALLET
# include <wallet/rpcwallet.h>
# include <wallet/wallet.h>
#endif

#include <univalue.h>

#include <boost/xpressive/xpressive_dynamic.hpp>

#include <algorithm>
#include <cassert>
#include <memory>
#include <stdexcept>

namespace
{

NameEncoding
EncodingFromOptionsJson (const UniValue& options, const std::string& field,
                         const NameEncoding defaultValue)
{
  NameEncoding res = defaultValue;
  RPCTypeCheckObj (options,
    {
      {field, UniValueType (UniValue::VSTR)},
    },
    true, false);
  if (options.exists (field))
    try
      {
        res = EncodingFromString (options[field].get_str ());
      }
    catch (const std::invalid_argument& exc)
      {
        LogPrintf ("Invalid value for %s in options: %s\n  using default %s\n",
                   field, exc.what (), EncodingToString (defaultValue));
      }

  return res;
}

} // anonymous namespace

/**
 * Utility routine to construct a "name info" object to return.  This is used
 * for name_show and also name_list.
 */
UniValue
getNameInfo (const UniValue& options,
             const valtype& name, const valtype& value,
             const COutPoint& outp, const CScript& addr)
{
  UniValue obj(UniValue::VOBJ);
  AddEncodedNameToUniv (obj, "name", name,
                        EncodingFromOptionsJson (options, "nameEncoding",
                                                 ConfiguredNameEncoding ()));
  AddEncodedNameToUniv (obj, "value", value,
                        EncodingFromOptionsJson (options, "valueEncoding",
                                                 ConfiguredValueEncoding ()));
  obj.pushKV ("txid", outp.hash.GetHex ());
  obj.pushKV ("vout", static_cast<int> (outp.n));

  /* Try to extract the address.  May fail if we can't parse the script
     as a "standard" script.  */
  CTxDestination dest;
  std::string addrStr;
  if (ExtractDestination (addr, dest))
    addrStr = EncodeDestination (dest);
  else
    addrStr = "<nonstandard>";
  obj.pushKV ("address", addrStr);

  return obj;
}

/**
 * Return name info object for a CNameData object.
 */
UniValue
getNameInfo (const UniValue& options,
             const valtype& name, const CNameData& data)
{
  UniValue result = getNameInfo (options,
                                 name, data.getValue (),
                                 data.getUpdateOutpoint (),
                                 data.getAddress ());
  addHeightInfo (data.getHeight (), result);
  return result;
}

void
addHeightInfo (const int height, UniValue& data)
{
  data.pushKV ("height", height);
}

#ifdef ENABLE_WALLET
/**
 * Adds the "ismine" field giving ownership info to the JSON object.
 */
void
addOwnershipInfo (const CScript& addr, const CWallet* pwallet,
                  UniValue& data)
{
  if (pwallet == nullptr)
    return;

  AssertLockHeld (pwallet->cs_wallet);
  const isminetype mine = pwallet->IsMine (addr);
  const bool isMine = (mine & ISMINE_SPENDABLE);
  data.pushKV ("ismine", isMine);
}
#endif

namespace
{

valtype
DecodeNameValueFromRPCOrThrow (const UniValue& val, const UniValue& opt,
                               const std::string& optKey,
                               const NameEncoding defaultEnc)
{
  const NameEncoding enc = EncodingFromOptionsJson (opt, optKey, defaultEnc);
  try
    {
      return DecodeName (val.get_str (), enc);
    }
  catch (const InvalidNameString& exc)
    {
      std::ostringstream msg;
      msg << "Name/value is invalid for encoding " << EncodingToString (enc);
      throw JSONRPCError (RPC_NAME_INVALID_ENCODING, msg.str ());
    }
}

} // anonymous namespace

valtype
DecodeNameFromRPCOrThrow (const UniValue& val, const UniValue& opt)
{
  return DecodeNameValueFromRPCOrThrow (val, opt, "nameEncoding",
                                        ConfiguredNameEncoding ());
}

valtype
DecodeValueFromRPCOrThrow (const UniValue& val, const UniValue& opt)
{
  return DecodeNameValueFromRPCOrThrow (val, opt, "valueEncoding",
                                        ConfiguredValueEncoding ());
}

namespace
{

/**
 * Helper class that extracts the wallet for the current RPC request, if any.
 * It handles the case of disabled wallet support or no wallet being present,
 * so that it is suitable for the non-wallet RPCs here where we just want to
 * provide optional extra features (like the "ismine" field).
 *
 * The main benefit of having this class is that we can easily LOCK2 with the
 * wallet and another lock we need, without having to care about the special
 * cases where no wallet is present or wallet support is disabled.
 */
class MaybeWalletForRequest
{

private:

#ifdef ENABLE_WALLET
  std::shared_ptr<CWallet> wallet;
#endif

public:

  explicit MaybeWalletForRequest (const JSONRPCRequest& request)
  {
#ifdef ENABLE_WALLET
    wallet = GetWalletForJSONRPCRequest (request);
#endif
  }

  RecursiveMutex*
  getLock () const
  {
#ifdef ENABLE_WALLET
    return (wallet != nullptr ? &wallet->cs_wallet : nullptr);
#else
    return nullptr;
#endif
  }

#ifdef ENABLE_WALLET
  CWallet*
  getWallet ()
  {
    return wallet.get ();
  }

  const CWallet*
  getWallet () const
  {
    return wallet.get ();
  }
#endif

};

/**
 * Variant of addOwnershipInfo that uses a MaybeWalletForRequest.  This takes
 * care of disabled wallet support.
 */
void
addOwnershipInfo (const CScript& addr, const MaybeWalletForRequest& wallet,
                  UniValue& data)
{
#ifdef ENABLE_WALLET
  addOwnershipInfo (addr, wallet.getWallet (), data);
#endif
}

/**
 * Utility variant of getNameInfo that already includes ownership information.
 * This is the most common call for methods in this file.
 */
UniValue
getNameInfo (const UniValue& options,
             const valtype& name, const CNameData& data,
             const MaybeWalletForRequest& wallet)
{
  UniValue res = getNameInfo (options, name, data);
  addOwnershipInfo (data.getAddress (), wallet, res);
  return res;
}

} // anonymous namespace

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

NameInfoHelp::NameInfoHelp ()
{
  withField ({RPCResult::Type::STR, "name", "the requested name"});
  withField ({RPCResult::Type::STR, "name_encoding", "the encoding of \"name\""});
  withField ({RPCResult::Type::STR, "name_error",
              "replaces \"name\" in case there is an error"});
  withField ({RPCResult::Type::STR, "value", "the name's current value"});
  withField ({RPCResult::Type::STR, "value_encoding", "the encoding of \"value\""});
  withField ({RPCResult::Type::STR, "value_error",
              "replaces \"value\" in case there is an error"});

  withField ({RPCResult::Type::STR_HEX, "txid", "the name's last update tx"});
  withField ({RPCResult::Type::NUM, "vout",
              "the index of the name output in the last update"});
  withField ({RPCResult::Type::STR, "address", "the address holding the name"});
#ifdef ENABLE_WALLET
  withField ({RPCResult::Type::BOOL, "ismine",
              "whether the name is owned by the wallet"});
#endif
}

NameInfoHelp&
NameInfoHelp::withHeight ()
{
  withField ({RPCResult::Type::NUM, "height", "the name's last update height"});
  return *this;
}

NameOptionsHelp::NameOptionsHelp ()
{}

NameOptionsHelp&
NameOptionsHelp::withArg (const std::string& name, const RPCArg::Type type,
                          const std::string& doc)
{
  return withArg (name, type, "", doc);
}

NameOptionsHelp&
NameOptionsHelp::withArg (const std::string& name, const RPCArg::Type type,
                          const std::string& defaultValue,
                          const std::string& doc)
{
  if (defaultValue.empty ())
    innerArgs.push_back (RPCArg (name, type, RPCArg::Optional::OMITTED, doc));
  else
    innerArgs.push_back (RPCArg (name, type, defaultValue, doc));

  return *this;
}

NameOptionsHelp&
NameOptionsHelp::withWriteOptions ()
{
  withArg ("destAddress", RPCArg::Type::STR,
           "The address to send the name output to");

  withArg ("sendCoins", RPCArg::Type::OBJ_USER_KEYS,
           "Addresses to which coins should be sent additionally");

  withArg ("burn", RPCArg::Type::OBJ_USER_KEYS,
           "Data and amounts of CHI to burn in the transaction");

  return *this;
}

NameOptionsHelp&
NameOptionsHelp::withNameEncoding ()
{
  withArg ("nameEncoding", RPCArg::Type::STR,
           "Encoding (\"ascii\", \"utf8\" or \"hex\") of the name argument");
  return *this;
}

NameOptionsHelp&
NameOptionsHelp::withValueEncoding ()
{
  withArg ("valueEncoding", RPCArg::Type::STR,
           "Encoding (\"ascii\", \"utf8\" or \"hex\") of the value argument");
  return *this;
}

RPCArg
NameOptionsHelp::buildRpcArg () const
{
  return RPCArg ("options", RPCArg::Type::OBJ,
                 RPCArg::Optional::OMITTED_NAMED_ARG,
                 "Options for this RPC call",
                 innerArgs, "options");
}

/* ************************************************************************** */
namespace
{

UniValue
name_show (const JSONRPCRequest& request)
{
  NameOptionsHelp optHelp;
  optHelp
      .withNameEncoding ()
      .withValueEncoding ();

  RPCHelpMan ("name_show",
      "\nLooks up the current data for the given name.  Fails if the name doesn't exist.\n",
      {
          {"name", RPCArg::Type::STR, RPCArg::Optional::NO, "The name to query for"},
          optHelp.buildRpcArg (),
      },
      NameInfoHelp ()
        .withHeight ()
        .finish (),
      RPCExamples {
          HelpExampleCli ("name_show", "\"myname\"")
        + HelpExampleRpc ("name_show", "\"myname\"")
      }
  ).Check (request);

  RPCTypeCheck (request.params, {UniValue::VSTR, UniValue::VOBJ});

  if (::ChainstateActive ().IsInitialBlockDownload ())
    throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD,
                       "Xaya is downloading blocks...");

  UniValue options(UniValue::VOBJ);
  if (request.params.size () >= 2)
    options = request.params[1].get_obj ();

  const valtype name
      = DecodeNameFromRPCOrThrow (request.params[0], options);

  CNameData data;
  {
    LOCK (cs_main);
    if (!::ChainstateActive ().CoinsTip ().GetName (name, data))
      {
        std::ostringstream msg;
        msg << "name not found: " << EncodeNameForMessage (name);
        throw JSONRPCError (RPC_WALLET_ERROR, msg.str ());
      }
  }

  MaybeWalletForRequest wallet(request);
  LOCK2 (cs_main, wallet.getLock ());
  return getNameInfo (options, name, data, wallet);
}

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

UniValue
name_history (const JSONRPCRequest& request)
{
  NameOptionsHelp optHelp;
  optHelp
      .withNameEncoding ()
      .withValueEncoding ();

  RPCHelpMan ("name_history",
      "\nLooks up the current and all past data for the given name.  -namehistory must be enabled.\n",
      {
          {"name", RPCArg::Type::STR, RPCArg::Optional::NO, "The name to query for"},
          optHelp.buildRpcArg (),
      },
      RPCResult {RPCResult::Type::ARR, "", "",
          {
              NameInfoHelp ()
                .withHeight ()
                .finish ()
          }
      },
      RPCExamples {
          HelpExampleCli ("name_history", "\"myname\"")
        + HelpExampleRpc ("name_history", "\"myname\"")
      }
  ).Check (request);

  RPCTypeCheck (request.params, {UniValue::VSTR, UniValue::VOBJ});

  if (!fNameHistory)
    throw std::runtime_error ("-namehistory is not enabled");

  if (::ChainstateActive ().IsInitialBlockDownload ())
    throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD,
                       "Xaya is downloading blocks...");

  UniValue options(UniValue::VOBJ);
  if (request.params.size () >= 2)
    options = request.params[1].get_obj ();

  const valtype name
      = DecodeNameFromRPCOrThrow (request.params[0], options);

  CNameData data;
  CNameHistory history;

  {
    LOCK (cs_main);

    const auto& coinsTip = ::ChainstateActive ().CoinsTip ();
    if (!coinsTip.GetName (name, data))
      {
        std::ostringstream msg;
        msg << "name not found: " << EncodeNameForMessage (name);
        throw JSONRPCError (RPC_WALLET_ERROR, msg.str ());
      }

    if (!coinsTip.GetNameHistory (name, history))
      assert (history.empty ());
  }

  MaybeWalletForRequest wallet(request);
  LOCK2 (cs_main, wallet.getLock ());

  UniValue res(UniValue::VARR);
  for (const auto& entry : history.getData ())
    res.push_back (getNameInfo (options, name, entry, wallet));
  res.push_back (getNameInfo (options, name, data, wallet));

  return res;
}

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

UniValue
name_scan (const JSONRPCRequest& request)
{
  NameOptionsHelp optHelp;
  optHelp
      .withNameEncoding ()
      .withValueEncoding ()
      .withArg ("minConf", RPCArg::Type::NUM, "1",
                "Minimum number of confirmations")
      .withArg ("maxConf", RPCArg::Type::NUM,
                "Maximum number of confirmations")
      .withArg ("prefix", RPCArg::Type::STR,
                "Filter for names with the given prefix")
      .withArg ("regexp", RPCArg::Type::STR,
                "Filter for names matching the regexp");

  RPCHelpMan ("name_scan",
      "\nLists names in the database.\n",
      {
          {"start", RPCArg::Type::STR, "", "Skip initially to this name"},
          {"count", RPCArg::Type::NUM, "500", "Stop after this many names"},
          optHelp.buildRpcArg (),
      },
      RPCResult {RPCResult::Type::ARR, "", "",
          {
              NameInfoHelp ()
                .withHeight ()
                .finish ()
          }
      },
      RPCExamples {
          HelpExampleCli ("name_scan", "")
        + HelpExampleCli ("name_scan", "\"d/abc\"")
        + HelpExampleCli ("name_scan", "\"d/abc\" 10")
        + HelpExampleRpc ("name_scan", "\"d/abc\"")
      }
  ).Check (request);

  RPCTypeCheck (request.params,
                {UniValue::VSTR, UniValue::VNUM, UniValue::VOBJ});

  if (::ChainstateActive ().IsInitialBlockDownload ())
    throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD,
                       "Xaya is downloading blocks...");

  UniValue options(UniValue::VOBJ);
  if (request.params.size () >= 3)
    options = request.params[2].get_obj ();

  valtype start;
  if (request.params.size () >= 1)
    start = DecodeNameFromRPCOrThrow (request.params[0], options);

  int count = 500;
  if (request.params.size () >= 2)
    count = request.params[1].get_int ();

  /* Parse and interpret the name_scan-specific options.  */
  RPCTypeCheckObj (options,
    {
      {"minConf", UniValueType (UniValue::VNUM)},
      {"maxConf", UniValueType (UniValue::VNUM)},
      {"prefix", UniValueType (UniValue::VSTR)},
      {"regexp", UniValueType (UniValue::VSTR)},
    },
    true, false);

  int minConf = 1;
  if (options.exists ("minConf"))
    minConf = options["minConf"].get_int ();
  if (minConf < 1)
    throw JSONRPCError (RPC_INVALID_PARAMETER, "minConf must be >= 1");

  int maxConf = -1;
  if (options.exists ("maxConf"))
    {
      maxConf = options["maxConf"].get_int ();
      if (maxConf < 0)
        throw JSONRPCError (RPC_INVALID_PARAMETER,
                            "maxConf must not be negative");
    }

  valtype prefix;
  if (options.exists ("prefix"))
    prefix = DecodeNameFromRPCOrThrow (options["prefix"], options);

  bool haveRegexp = false;
  boost::xpressive::sregex regexp;
  if (options.exists ("regexp"))
    {
      haveRegexp = true;
      regexp = boost::xpressive::sregex::compile (options["regexp"].get_str ());
    }

  /* Iterate over names and produce the result.  */
  UniValue res(UniValue::VARR);
  if (count <= 0)
    return res;

  MaybeWalletForRequest wallet(request);
  LOCK2 (cs_main, wallet.getLock ());

  const int maxHeight = ::ChainActive ().Height () - minConf + 1;
  int minHeight = -1;
  if (maxConf >= 0)
    minHeight = ::ChainActive ().Height () - maxConf + 1;

  valtype name;
  CNameData data;
  const auto& coinsTip = ::ChainstateActive ().CoinsTip ();
  std::unique_ptr<CNameIterator> iter(coinsTip.IterateNames ());
  for (iter->seek (start); count > 0 && iter->next (name, data); )
    {
      const int height = data.getHeight ();
      if (height > maxHeight)
        continue;
      if (minHeight >= 0 && height < minHeight)
        continue;

      if (name.size () < prefix.size ())
        continue;
      if (!std::equal (prefix.begin (), prefix.end (), name.begin ()))
        continue;

      if (haveRegexp)
        {
          try
            {
              const std::string nameStr = EncodeName (name, NameEncoding::UTF8);
              boost::xpressive::smatch matches;
              if (!boost::xpressive::regex_search (nameStr, matches, regexp))
                continue;
            }
          catch (const InvalidNameString& exc)
            {
              continue;
            }
        }

      res.push_back (getNameInfo (options, name, data, wallet));
      --count;
    }

  return res;
}

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

UniValue
name_pending (const JSONRPCRequest& request)
{
  NameOptionsHelp optHelp;
  optHelp
      .withNameEncoding ()
      .withValueEncoding ();

  RPCHelpMan ("name_pending",
      "\nLists unconfirmed name operations in the mempool.\n"
      "\nIf a name is given, only check for operations on this name.\n",
      {
          {"name", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Only look for this name"},
          optHelp.buildRpcArg (),
      },
      RPCResult {RPCResult::Type::ARR, "", "",
          {
              NameInfoHelp ()
                .withField ({RPCResult::Type::STR, "op", "the operation being performed"})
                .withHeight ()
                .finish ()
          }
      },
      RPCExamples {
          HelpExampleCli ("name_pending", "")
        + HelpExampleCli ("name_pending", "\"d/domob\"")
        + HelpExampleRpc ("name_pending", "")
      }
  ).Check (request);

  RPCTypeCheck (request.params, {UniValue::VSTR, UniValue::VOBJ}, true);

  MaybeWalletForRequest wallet(request);
  LOCK2 (wallet.getLock (), mempool.cs);

  UniValue options(UniValue::VOBJ);
  if (request.params.size () >= 2)
    options = request.params[1].get_obj ();

  std::vector<uint256> txHashes;
  mempool.queryHashes (txHashes);

  const bool hasNameFilter = !request.params[0].isNull ();
  valtype nameFilter;
  if (hasNameFilter)
    nameFilter = DecodeNameFromRPCOrThrow (request.params[0], options);

  UniValue arr(UniValue::VARR);
  for (const auto& txHash : txHashes)
    {
      std::shared_ptr<const CTransaction> tx = mempool.get (txHash);
      if (!tx)
        continue;

      for (size_t n = 0; n < tx->vout.size (); ++n)
        {
          const auto& txOut = tx->vout[n];
          const CNameScript op(txOut.scriptPubKey);
          if (!op.isNameOp () || !op.isAnyUpdate ())
            continue;
          if (hasNameFilter && op.getOpName () != nameFilter)
            continue;

          UniValue obj = getNameInfo (options,
                                      op.getOpName (), op.getOpValue (),
                                      COutPoint (tx->GetHash (), n),
                                      op.getAddress ());
          addOwnershipInfo (op.getAddress (), wallet, obj);
          switch (op.getNameOp ())
            {
            case OP_NAME_REGISTER:
              obj.pushKV ("op", "name_register");
              break;
            case OP_NAME_UPDATE:
              obj.pushKV ("op", "name_update");
              break;
            default:
              assert (false);
            }

          arr.push_back (obj);
        }
    }

  return arr;
}

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

UniValue
namerawtransaction (const JSONRPCRequest& request)
{
  RPCHelpMan ("namerawtransaction",
      "\nAdds a name operation to an existing raw transaction.\n"
      "\nUse createrawtransaction first to create the basic transaction, including the required inputs and outputs also for the name.\n",
      {
          {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction hex string"},
          {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The vout of the desired name output"},
          {"nameop", RPCArg::Type::OBJ, RPCArg::Optional::NO, "The name operation to create",
              {
                  {"op", RPCArg::Type::STR, RPCArg::Optional::NO, "The operation to perform, can be \"name_new\", \"name_firstupdate\" and \"name_update\""},
                  {"name", RPCArg::Type::STR, RPCArg::Optional::NO, "The name to operate on"},
                  {"value", RPCArg::Type::STR, RPCArg::Optional::NO, "The new value for the name"},
              },
           "nameop"},
      },
      RPCResult {RPCResult::Type::OBJ, "", "",
          {
              {RPCResult::Type::STR_HEX, "hex", "Hex string of the updated transaction"},
          },
      },
      RPCExamples {
          HelpExampleCli ("namerawtransaction", R"("raw tx hex" 1 "{\"op\":\"name_register\",\"name\":\"my-name\",\"value\":\"new value\")")
        + HelpExampleCli ("namerawtransaction", R"("raw tx hex" 1 "{\"op\":\"name_update\",\"name\":\"my-name\",\"value\":\"new value\")")
        + HelpExampleRpc ("namerawtransaction", R"("raw tx hex", 1, "{\"op\":\"name_update\",\"name\":\"my-name\",\"value\":\"new value\")")
      }
  ).Check (request);

  RPCTypeCheck (request.params,
                {UniValue::VSTR, UniValue::VNUM, UniValue::VOBJ});

  CMutableTransaction mtx;
  if (!DecodeHexTx (mtx, request.params[0].get_str (), true))
    throw JSONRPCError (RPC_DESERIALIZATION_ERROR, "TX decode failed");

  const size_t nOut = request.params[1].get_int ();
  if (nOut >= mtx.vout.size ())
    throw JSONRPCError (RPC_INVALID_PARAMETER, "vout is out of range");

  /* namerawtransaction does not have an options argument.  This would just
     make the already long list of arguments longer.  Instead of using
     namerawtransaction, namecoin-tx can be used anyway to create name
     operations with arbitrary hex data.  */
  const UniValue NO_OPTIONS(UniValue::VOBJ);

  const UniValue nameOp = request.params[2].get_obj ();
  RPCTypeCheckObj (nameOp,
    {
      {"op", UniValueType (UniValue::VSTR)},
      {"name", UniValueType (UniValue::VSTR)},
      {"value", UniValueType (UniValue::VSTR)},
    }
  );
  const std::string op = find_value (nameOp, "op").get_str ();
  const valtype name
    = DecodeNameFromRPCOrThrow (find_value (nameOp, "name"), NO_OPTIONS);
  const valtype value
    = DecodeValueFromRPCOrThrow (find_value (nameOp, "value"), NO_OPTIONS);

  UniValue result(UniValue::VOBJ);

  if (op == "name_register")
    mtx.vout[nOut].scriptPubKey
      = CNameScript::buildNameRegister (mtx.vout[nOut].scriptPubKey,
                                        name, value);
  else if (op == "name_update")
    mtx.vout[nOut].scriptPubKey
      = CNameScript::buildNameUpdate (mtx.vout[nOut].scriptPubKey,
                                      name, value);
  else
    throw JSONRPCError (RPC_INVALID_PARAMETER, "Invalid name operation");

  result.pushKV ("hex", EncodeHexTx (CTransaction (mtx)));
  return result;
}

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

UniValue
name_checkdb (const JSONRPCRequest& request)
{
  RPCHelpMan ("name_checkdb",
      "\nValidates the name DB's consistency.\n"
      "\nRoughly between blocks 139,000 and 180,000, this call is expected to fail due to the historic 'name stealing' bug.\n",
      {},
      RPCResult {RPCResult::Type::BOOL, "", "whether the state is valid"},
      RPCExamples {
          HelpExampleCli ("name_checkdb", "")
        + HelpExampleRpc ("name_checkdb", "")
      }
  ).Check (request);

  LOCK (cs_main);
  auto& coinsTip = ::ChainstateActive ().CoinsTip ();
  coinsTip.Flush ();
  return coinsTip.ValidateNameDB ();
}

} // namespace
/* ************************************************************************** */

void RegisterNameRPCCommands(CRPCTable &t)
{
static const CRPCCommand commands[] =
{ //  category              name                      actor (function)         argNames
  //  --------------------- ------------------------  -----------------------  ----------
    { "names",              "name_show",              &name_show,              {"name","options"} },
    { "names",              "name_history",           &name_history,           {"name","options"} },
    { "names",              "name_scan",              &name_scan,              {"start","count","options"} },
    { "names",              "name_pending",           &name_pending,           {"name","options"} },
    { "names",              "name_checkdb",           &name_checkdb,           {} },
    { "rawtransactions",    "namerawtransaction",     &namerawtransaction,     {"hexstring","vout","nameop"} },
};

    for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
        t.appendCommand(commands[vcidx].name, &commands[vcidx]);
}

max_stars_repo_name: cryptocrowd-city/xcrc-core-wallet

max_issues_repo_name: cryptocrowd-city/xcrc-core-wallet

max_forks_repo_name: cryptocrowd-city/xcrc-core-wallet