<commit_before>#include <chord.h>
#include <modlogger.h>
#include <id_utils.h>
#include "merkle.h"
#include "merkle_tree_disk.h"
#include <location.h>
#include <transport_prot.h>
#include <comm.h>

// {{{ Globals
static struct {
  ptr<merkle_tree> tree;
  ptr<merkle_server> server;
  ptr<asrv> srv;
} SERVER;

static struct {
  ptr<merkle_tree> tree;
  ptr<merkle_syncer> syncer;
  ptr<aclnt> clnt;
} SYNCER;

u_int32_t nkeyspushed = 0;
u_int32_t nkeyspulled = 0;
vec<chordID> keys_for_server;
vec<chordID> keys_for_syncer;

str server_index = "/tmp/server.index.mrk";
str server_internal = "/tmp/server.internal.mrk";
str server_leaf = "/tmp/server.leaf.mrk";
str syncer_index = "/tmp/syncer.index.mrk";
str syncer_internal = "/tmp/syncer.internal.mrk";
str syncer_leaf = "/tmp/syncer.leaf.mrk";
// }}}

// {{{ RPC Magic
static void
doRPCcb (xdrproc_t proc, dorpc_res *res, aclnt_cb cb, void *out, clnt_stat err)
{
  xdrmem x ((char *)res->resok->results.base (),
	    res->resok->results.size (), XDR_DECODE);

  if (err) {
    warnx << "doRPC: err = " << err << "\n";
    assert (!err);
  } else if (!proc (x.xdrp (), out)) {
    warnx << "failed to unmarshall result\n";
    cb (RPC_CANTSEND);
    return;
  }
  cb (err);
  delete res;
}

// called by syncer to perform merkle RPC to server
static void
doRPC (RPC_delay_args *a)
{
  //form the transport RPC
  ptr<dorpc_arg> arg = New refcounted<dorpc_arg> ();
  // Other fields don't matter.
  arg->progno = a->prog.progno;
  arg->procno = a->procno;

  xdrproc_t inproc = a->prog.tbl[a->procno].xdr_arg;
  xdrproc_t outproc = a->prog.tbl[a->procno].xdr_res;
  assert (outproc);
  xdrsuio x (XDR_ENCODE);
  if ((!inproc) || (!inproc (x.xdrp (), (void *)a->in))) {
    fatal << "failed to marshall args\n";
  }
  int args_len = x.uio ()->resid ();
  arg->args.setsize (args_len);
  void *marshalled_args = suio_flatten (x.uio ());
  memcpy (arg->args.base (), marshalled_args, args_len);
  free (marshalled_args);

  dorpc_res *res = New dorpc_res (DORPC_OK);
  SYNCER.clnt->call (TRANSPORTPROC_DORPC, arg, res,
                     wrap (&doRPCcb, outproc, res, a->cb, a->out));
}

vec<const rpc_program *> handledProgs;
vec<cbdispatch_t> handlers;

static void
transport_dispatch (svccb *sbp)
{
  if (!sbp) {
    warnx << "transport server eof\n";
    return;
  }

  dorpc_arg *arg = sbp->Xtmpl getarg<dorpc_arg> ();

  chord_node_wire nw;
  bzero (&nw, sizeof (chord_node_wire));

  const rpc_program *prog (NULL);
  unsigned int i (0);
  for (unsigned int i = 0; i < handledProgs.size (); i++)
    if (arg->progno == (int)handledProgs[i]->progno) {
      prog = handledProgs[i];
      break;
    }
  char *arg_base = (char *)(arg->args.base ());
  int arg_len = arg->args.size ();

  xdrmem x (arg_base, arg_len, XDR_DECODE);
  xdrproc_t proc = prog->tbl[arg->procno].xdr_arg;
  assert (proc);

  void *unmarshalled_args = prog->tbl[arg->procno].alloc_arg ();
  if (!proc (x.xdrp (), unmarshalled_args)) {
    warn << "dispatch: error unmarshalling arguments: "
	 << arg->progno << "." << arg->procno << "\n";
    xdr_delete (prog->tbl[arg->procno].xdr_arg, unmarshalled_args);
    sbp->replyref (rpcstat (DORPC_MARSHALLERR));
    return;
  }
  user_args *ua = New user_args (sbp, unmarshalled_args,
				 prog, arg->procno, 0);
  ua->me_ = New refcounted<location> (make_chord_node (nw));
  handlers[i] (ua);
}

// called by server to register handler fielding merkle RPCs
static void
addHandler (const rpc_program &prog, cbdispatch_t cb)
{
  handledProgs.push_back (&prog);
  handlers.push_back (cb);
}
// }}}
// {{{ Testing framework - setup/finish/addrand/dump_stats
static void
sendblock (bigint blockID, bool missingLocal)
{
  if (missingLocal)
    keys_for_syncer.push_back (blockID);
  else
    keys_for_server.push_back (blockID);
}

void
dump_stats ()
{
  warn  << "+++++++++++++++++++++++++SERVER.tree++++++++++++++++++++++++++++++\n";
  SERVER.tree->compute_stats ();
  // SERVER.tree->dump ();
  warn  << "+++++++++++++++++++++++++SYNCER.tree++++++++++++++++++++++++++++++\n";
  SYNCER.tree->compute_stats ();
  // SYNCER.tree->dump ();
}

void
setup ()
{
  warn << "===> setup() +++++++++++++++++++++++++++\n";
  SERVER.tree = New refcounted<merkle_tree_disk> (server_index,
						  server_internal, server_leaf,
						  true);
  SYNCER.tree = New refcounted<merkle_tree_disk> (syncer_index,
						  syncer_internal, syncer_leaf,
						  true);

  // these are closed by axprt_stream's dtor, right?
  int fds[2];
  assert (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) == 0);
  warn << "  sockets: " << fds[0] << ":" << fds[1] << "\n";
  SERVER.srv = asrv::alloc (axprt_stream::alloc (fds[0]), transport_program_1);
  SYNCER.clnt = aclnt::alloc (axprt_stream::alloc (fds[1]), transport_program_1);
  assert (SERVER.srv && SYNCER.clnt);
  SERVER.srv->setcb (wrap (&transport_dispatch));

  SYNCER.syncer = New refcounted<merkle_syncer> (0, DHASH_CONTENTHASH,
						 SYNCER.tree,
						 wrap (doRPC),
						 wrap (sendblock));
  SERVER.server = New refcounted<merkle_server> (SERVER.tree);
  addHandler (merklesync_program_1,
      wrap (SERVER.server, &merkle_server::dispatch));
  err_flush ();
}

void
finish ()
{
  // Force all destructors to be called, hopefully.
  handledProgs.clear ();
  handlers.clear ();

  SYNCER.syncer = NULL;
  SERVER.server = NULL;
  SYNCER.clnt = NULL;
  SERVER.srv  = NULL;
  SYNCER.tree = NULL;
  SERVER.tree = NULL;

  unlink (server_index);
  unlink (server_internal);
  unlink (server_leaf);

  unlink (syncer_index);
  unlink (syncer_internal);
  unlink (syncer_leaf);
}

void
addrand (ptr<merkle_tree> tr, int count)
{
  for (int i = 0; i < count; i++) {
    merkle_hash key;
    key.randomize ();
    tr->insert (key);
    if ((i % 1000) == 0) {
      warn << "inserted " << i << " blocks..of " << count << "\n";
      err_flush ();
    }
  }
}

void
check_invariants ()
{
  warn << "Checking server invariants... ";
  SERVER.tree->check_invariants ();
  warn << "OK\n";
  warn << "Checking syncer invariants... ";
  SYNCER.tree->check_invariants ();
  warn << "OK\n";
}

void check_equal_roots ()
{
  warn << "Checking that roots are equal... ";
  merkle_node *serv_root = SERVER.tree->get_root ();
  merkle_node *sync_root = SYNCER.tree->get_root ();
  if (serv_root->hash != sync_root->hash) {
    warn << "SERVER.tree->root " << serv_root->hash << " cnt " << serv_root->count << "\n";
    warn << "SYNCER.tree->root " << sync_root->hash << " cnt " << sync_root->count << "\n";
    fatal << "NOT OK!\n";
  }
  SERVER.tree->lookup_release (serv_root);
  SYNCER.tree->lookup_release (sync_root);
  warn << "OK\n";
}
// }}}

void
runsync (chordID rngmin, chordID rngmax)
{
  nkeyspushed = 0;
  nkeyspulled = 0;
  SYNCER.syncer->sync (rngmin, rngmax);
  while (!SYNCER.syncer->done ()) {
    acheck ();

    while (keys_for_server.size ()) {
      chordID k = keys_for_server.pop_front ();
      merkle_hash key = to_merkle_hash (k);
      SERVER.tree->insert (key);
      nkeyspushed++;
    }
    while (keys_for_syncer.size ()) {
      chordID k = keys_for_syncer.pop_front ();
      merkle_hash key = to_merkle_hash (k);
      SYNCER.tree->insert (key);
      nkeyspulled++;
    }
  }
}

int
main (int argc, char *argv[])
{
  if (argc > 1)
    modlogger::setmaxprio (modlogger::TRACE);

  // Make sure no old state remains on disk.
  finish ();

  bigint idzero = 0;
  bigint idmax  = (bigint (1) << 160)  - 1;

  // Empty A, Empty B, Complete range
  // ==> A should equal B.
  // ==> Resync should move no keys.
  setup ();
  runsync (idzero, idmax);
  check_invariants ();
  assert (nkeyspushed == 0);
  assert (nkeyspulled == 0);
  check_equal_roots ();
  runsync (idzero, idmax);
  check_invariants ();
  assert (nkeyspushed == 0);
  assert (nkeyspulled == 0);
  dump_stats ();
  finish ();

  // Empty A, Non-empty B, Complete range
  // ==> A should equal B.
  // ==> Resync should move no keys.
  setup ();
  addrand (SERVER.tree, 256);
  runsync (idzero, idmax);
  check_invariants ();
  check_equal_roots ();
  runsync (idzero, idmax);
  check_invariants ();
  assert (nkeyspushed == 0);
  assert (nkeyspulled == 0);
  dump_stats ();
  finish ();

  // Non-empty A, Empty B, Complete range
  // ==> A should equal B.
  // ==> Resync should move no keys.
  setup ();
  addrand (SYNCER.tree, 1024);
  runsync (idzero, idmax);
  check_invariants ();
  check_equal_roots ();
  runsync (idzero, idmax);
  check_invariants ();
  assert (nkeyspushed == 0);
  assert (nkeyspulled == 0);
  dump_stats ();
  finish ();

  // Non-empty A, Non-empty B, Complete range
  // ==> A should equal B.
  // ==> Resync should move no keys.
  setup ();
  addrand (SYNCER.tree, 4097);
  addrand (SERVER.tree, 4097);
  runsync (idzero, idmax);
  check_invariants ();
  check_equal_roots ();
  runsync (idzero, idmax);
  check_invariants ();
  assert (nkeyspushed == 0);
  assert (nkeyspulled == 0);
  dump_stats ();
  finish ();

  // XXX Should we test various degrees of commonality in A/B?
  //
  // Same as above, but for a partial range.
  // The results are that A will not equal B, but resync won't
  // exchange any keys.
}

/* vim:set foldmethod=marker: */
<commit_msg>test_merkle_syncer: Allow compile-time choice of disk vs memory merkle_tree.<commit_after>#include <chord.h>
#include <modlogger.h>
#include <id_utils.h>
#include "merkle.h"
#include "merkle_tree_disk.h"
#include <location.h>
#include <transport_prot.h>
#include <comm.h>

// {{{ Globals
static const bool usedisk = false;

static struct {
  ptr<merkle_tree> tree;
  ptr<merkle_server> server;
  ptr<asrv> srv;
} SERVER;

static struct {
  ptr<merkle_tree> tree;
  ptr<merkle_syncer> syncer;
  ptr<aclnt> clnt;
} SYNCER;

u_int32_t nkeyspushed = 0;
u_int32_t nkeyspulled = 0;
vec<chordID> keys_for_server;
vec<chordID> keys_for_syncer;

str server_index = "/tmp/server.index.mrk";
str server_internal = "/tmp/server.internal.mrk";
str server_leaf = "/tmp/server.leaf.mrk";
str syncer_index = "/tmp/syncer.index.mrk";
str syncer_internal = "/tmp/syncer.internal.mrk";
str syncer_leaf = "/tmp/syncer.leaf.mrk";
// }}}

// {{{ RPC Magic
static void
doRPCcb (xdrproc_t proc, dorpc_res *res, aclnt_cb cb, void *out, clnt_stat err)
{
  xdrmem x ((char *)res->resok->results.base (),
	    res->resok->results.size (), XDR_DECODE);

  if (err) {
    warnx << "doRPC: err = " << err << "\n";
    assert (!err);
  } else if (!proc (x.xdrp (), out)) {
    warnx << "failed to unmarshall result\n";
    cb (RPC_CANTSEND);
    return;
  }
  cb (err);
  delete res;
}

// called by syncer to perform merkle RPC to server
static void
doRPC (RPC_delay_args *a)
{
  //form the transport RPC
  ptr<dorpc_arg> arg = New refcounted<dorpc_arg> ();
  // Other fields don't matter.
  arg->progno = a->prog.progno;
  arg->procno = a->procno;

  xdrproc_t inproc = a->prog.tbl[a->procno].xdr_arg;
  xdrproc_t outproc = a->prog.tbl[a->procno].xdr_res;
  assert (outproc);
  xdrsuio x (XDR_ENCODE);
  if ((!inproc) || (!inproc (x.xdrp (), (void *)a->in))) {
    fatal << "failed to marshall args\n";
  }
  int args_len = x.uio ()->resid ();
  arg->args.setsize (args_len);
  void *marshalled_args = suio_flatten (x.uio ());
  memcpy (arg->args.base (), marshalled_args, args_len);
  free (marshalled_args);

  dorpc_res *res = New dorpc_res (DORPC_OK);
  SYNCER.clnt->call (TRANSPORTPROC_DORPC, arg, res,
                     wrap (&doRPCcb, outproc, res, a->cb, a->out));
}

vec<const rpc_program *> handledProgs;
vec<cbdispatch_t> handlers;

static void
transport_dispatch (svccb *sbp)
{
  if (!sbp) {
    warnx << "transport server eof\n";
    return;
  }

  dorpc_arg *arg = sbp->Xtmpl getarg<dorpc_arg> ();

  chord_node_wire nw;
  bzero (&nw, sizeof (chord_node_wire));

  const rpc_program *prog (NULL);
  unsigned int i (0);
  for (unsigned int i = 0; i < handledProgs.size (); i++)
    if (arg->progno == (int)handledProgs[i]->progno) {
      prog = handledProgs[i];
      break;
    }
  char *arg_base = (char *)(arg->args.base ());
  int arg_len = arg->args.size ();

  xdrmem x (arg_base, arg_len, XDR_DECODE);
  xdrproc_t proc = prog->tbl[arg->procno].xdr_arg;
  assert (proc);

  void *unmarshalled_args = prog->tbl[arg->procno].alloc_arg ();
  if (!proc (x.xdrp (), unmarshalled_args)) {
    warn << "dispatch: error unmarshalling arguments: "
	 << arg->progno << "." << arg->procno << "\n";
    xdr_delete (prog->tbl[arg->procno].xdr_arg, unmarshalled_args);
    sbp->replyref (rpcstat (DORPC_MARSHALLERR));
    return;
  }
  user_args *ua = New user_args (sbp, unmarshalled_args,
				 prog, arg->procno, 0);
  ua->me_ = New refcounted<location> (make_chord_node (nw));
  handlers[i] (ua);
}

// called by server to register handler fielding merkle RPCs
static void
addHandler (const rpc_program &prog, cbdispatch_t cb)
{
  handledProgs.push_back (&prog);
  handlers.push_back (cb);
}
// }}}
// {{{ Testing framework - setup/finish/addrand/dump_stats
static void
sendblock (bigint blockID, bool missingLocal)
{
  if (missingLocal)
    keys_for_syncer.push_back (blockID);
  else
    keys_for_server.push_back (blockID);
}

void
dump_stats ()
{
  warn  << "+++++++++++++++++++++++++SERVER.tree++++++++++++++++++++++++++++++\n";
  SERVER.tree->compute_stats ();
  // SERVER.tree->dump ();
  warn  << "+++++++++++++++++++++++++SYNCER.tree++++++++++++++++++++++++++++++\n";
  SYNCER.tree->compute_stats ();
  // SYNCER.tree->dump ();
}

void
setup ()
{
  warn << "===> setup() +++++++++++++++++++++++++++\n";
  if (usedisk) {
    SERVER.tree = New refcounted<merkle_tree_disk> (server_index,
						    server_internal, server_leaf,
						    true);
    SYNCER.tree = New refcounted<merkle_tree_disk> (syncer_index,
						    syncer_internal, syncer_leaf,
						    true);
  } else {
    SERVER.tree = New refcounted<merkle_tree> ();
    SYNCER.tree = New refcounted<merkle_tree> ();
  }

  // these are closed by axprt_stream's dtor, right?
  int fds[2];
  assert (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) == 0);
  warn << "  sockets: " << fds[0] << ":" << fds[1] << "\n";
  SERVER.srv = asrv::alloc (axprt_stream::alloc (fds[0]), transport_program_1);
  SYNCER.clnt = aclnt::alloc (axprt_stream::alloc (fds[1]), transport_program_1);
  assert (SERVER.srv && SYNCER.clnt);
  SERVER.srv->setcb (wrap (&transport_dispatch));

  SYNCER.syncer = New refcounted<merkle_syncer> (0, DHASH_CONTENTHASH,
						 SYNCER.tree,
						 wrap (doRPC),
						 wrap (sendblock));
  SERVER.server = New refcounted<merkle_server> (SERVER.tree);
  addHandler (merklesync_program_1,
      wrap (SERVER.server, &merkle_server::dispatch));
  err_flush ();
}

void
finish ()
{
  // Force all destructors to be called, hopefully.
  handledProgs.clear ();
  handlers.clear ();

  SYNCER.syncer = NULL;
  SERVER.server = NULL;
  SYNCER.clnt = NULL;
  SERVER.srv  = NULL;
  SYNCER.tree = NULL;
  SERVER.tree = NULL;

  if (usedisk) {
    unlink (server_index);
    unlink (server_internal);
    unlink (server_leaf);

    unlink (syncer_index);
    unlink (syncer_internal);
    unlink (syncer_leaf);
  }
}

void
addrand (ptr<merkle_tree> tr, int count)
{
  for (int i = 0; i < count; i++) {
    merkle_hash key;
    key.randomize ();
    tr->insert (key);
    if ((i % 1000) == 0) {
      warn << "inserted " << i << " blocks..of " << count << "\n";
      err_flush ();
    }
  }
}

void
check_invariants ()
{
  warn << "Checking server invariants... ";
  SERVER.tree->check_invariants ();
  warn << "OK\n";
  warn << "Checking syncer invariants... ";
  SYNCER.tree->check_invariants ();
  warn << "OK\n";
}

void check_equal_roots ()
{
  warn << "Checking that roots are equal... ";
  merkle_node *serv_root = SERVER.tree->get_root ();
  merkle_node *sync_root = SYNCER.tree->get_root ();
  if (serv_root->hash != sync_root->hash) {
    warn << "SERVER.tree->root " << serv_root->hash << " cnt " << serv_root->count << "\n";
    warn << "SYNCER.tree->root " << sync_root->hash << " cnt " << sync_root->count << "\n";
    fatal << "NOT OK!\n";
  }
  SERVER.tree->lookup_release (serv_root);
  SYNCER.tree->lookup_release (sync_root);
  warn << "OK\n";
}
// }}}

void
runsync (chordID rngmin, chordID rngmax)
{
  nkeyspushed = 0;
  nkeyspulled = 0;
  SYNCER.syncer->sync (rngmin, rngmax);
  while (!SYNCER.syncer->done ()) {
    acheck ();

    while (keys_for_server.size ()) {
      chordID k = keys_for_server.pop_front ();
      merkle_hash key = to_merkle_hash (k);
      SERVER.tree->insert (key);
      nkeyspushed++;
    }
    while (keys_for_syncer.size ()) {
      chordID k = keys_for_syncer.pop_front ();
      merkle_hash key = to_merkle_hash (k);
      SYNCER.tree->insert (key);
      nkeyspulled++;
    }
  }
}

int
main (int argc, char *argv[])
{
  if (argc > 1)
    modlogger::setmaxprio (modlogger::TRACE);

  // Make sure no old state remains on disk.
  finish ();

  bigint idzero = 0;
  bigint idmax  = (bigint (1) << 160)  - 1;

  // Empty A, Empty B, Complete range
  // ==> A should equal B.
  // ==> Resync should move no keys.
  setup ();
  runsync (idzero, idmax);
  check_invariants ();
  assert (nkeyspushed == 0);
  assert (nkeyspulled == 0);
  check_equal_roots ();
  runsync (idzero, idmax);
  check_invariants ();
  assert (nkeyspushed == 0);
  assert (nkeyspulled == 0);
  dump_stats ();
  finish ();

  // Empty A, Non-empty B, Complete range
  // ==> A should equal B.
  // ==> Resync should move no keys.
  setup ();
  addrand (SERVER.tree, 256);
  runsync (idzero, idmax);
  check_invariants ();
  check_equal_roots ();
  runsync (idzero, idmax);
  check_invariants ();
  assert (nkeyspushed == 0);
  assert (nkeyspulled == 0);
  dump_stats ();
  finish ();

  // Non-empty A, Empty B, Complete range
  // ==> A should equal B.
  // ==> Resync should move no keys.
  setup ();
  addrand (SYNCER.tree, 1024);
  runsync (idzero, idmax);
  check_invariants ();
  check_equal_roots ();
  runsync (idzero, idmax);
  check_invariants ();
  assert (nkeyspushed == 0);
  assert (nkeyspulled == 0);
  dump_stats ();
  finish ();

  // Non-empty A, Non-empty B, Complete range
  // ==> A should equal B.
  // ==> Resync should move no keys.
  setup ();
  addrand (SYNCER.tree, 4097);
  addrand (SERVER.tree, 4097);
  runsync (idzero, idmax);
  check_invariants ();
  check_equal_roots ();
  runsync (idzero, idmax);
  check_invariants ();
  assert (nkeyspushed == 0);
  assert (nkeyspulled == 0);
  dump_stats ();
  finish ();

  // XXX Should we test various degrees of commonality in A/B?
  //
  // Same as above, but for a partial range.
  // The results are that A will not equal B, but resync won't
  // exchange any keys.
}

/* vim:set foldmethod=marker: */
<|endoftext|>


<commit_before>#include "SimplePage.h"
#include <QtCore/QFile>
#include <QtCore/QTimer>
#include <QtCore/QCoreApplication>

namespace web {
namespace page {

class SimplePagePrivate
{
    public:
        QFile file;
        QByteArray data;
        QTimer timer;
};

const qint32 CACHE_INTERVAL = 1000 * 60;

SimplePage::SimplePage(QString fileName) :
    SimplePage(new SimplePagePrivate, fileName)
{
}

QByteArray SimplePage::getContent()
{
    Q_D(SimplePage);

    if ( d->data.isEmpty() ) {
            d->file.open( QIODevice::ReadOnly );

            while ( !d->file.atEnd() ) {
                    d->data.append(d->file.read(10000));
                    QCoreApplication::processEvents();
                }

            d->file.close();

            d->timer.setInterval( CACHE_INTERVAL );

            QObject::connect( &d->timer, &QTimer::timeout, [=]() {
                    d->data.clear();
                });

            d->timer.start();
        }

    return d->data;
}

SimplePage::SimplePage(SimplePagePrivate *pr, QString fileName) :
    d_ptr(pr)
{
    Q_D(SimplePage);
    d->file.setFileName(fileName);
}

}
}
<commit_msg>Files shouldnt be surely not 1 mb<commit_after>#include "SimplePage.h"
#include <QtCore/QFile>
#include <QtCore/QTimer>
#include <QtCore/QCoreApplication>

namespace web {
namespace page {

class SimplePagePrivate
{
    public:
        QFile file;
        QByteArray data;
        QTimer timer;
};

const qint32 CACHE_INTERVAL = 1000 * 60 * 60;

SimplePage::SimplePage(QString fileName) :
    SimplePage(new SimplePagePrivate, fileName)
{
}

QByteArray SimplePage::getContent()
{
    Q_D(SimplePage);

    if ( d->data.isEmpty() ) {
            d->file.open( QIODevice::ReadOnly );

            while ( !d->file.atEnd() ) {
                    d->data.append(d->file.read(800));
                    QCoreApplication::processEvents();
                }

            d->file.close();

            d->timer.setInterval( CACHE_INTERVAL );

            QObject::connect( &d->timer, &QTimer::timeout, [=]() {
                    d->data.clear();
                });

            d->timer.start();
        }

    return d->data;
}

SimplePage::SimplePage(SimplePagePrivate *pr, QString fileName) :
    d_ptr(pr)
{
    Q_D(SimplePage);
    d->file.setFileName(fileName);
}

}
}
<|endoftext|>


<commit_before>#include "vision_methods.hpp"
//#include <oepncv2/features2d.hpp>
#include <opencv2/opencv.hpp>

vision_methods::vision_methods () {
}

vision_methods::~vision_methods () {
}

cv::Mat vision_methods::preprocessing (const cv::Mat& image_in) {
    cv::Mat image_out;
    cvtColor (image_in, image_out, CV_BGR2GRAY);
    cv::GaussianBlur (image_out, image_out, cv::Size (_ksize_x, _ksize_y), _sigma_x, _sigma_y);
    return image_out;
}

cv::Mat vision_methods::segmentation (const cv::Mat& image_in) {
    cv::Mat image_out, image_thres;

    double otsus_threshold =
    cv::threshold (image_in, image_thres, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

    double CannyThresh = 0;

    cv::Canny (image_in, image_out, CannyThresh, otsus_threshold);

    return image_out;
}

cv::Mat vision_methods::extraction (const cv::Mat& image_in,
std::map<unsigned int, cv::KeyPoint>& markers) {
    std::vector<cv::KeyPoint> key_points;
    std::vector<cv::Vec4i> hierarchy;
    cv::RNG rng;
    cv::Mat image_out;

    // blob detection creation
    cv::SimpleBlobDetector::Params blob_detector_params;
    blob_detector_params.filterByArea        = true;
    blob_detector_params.maxArea             = 10000.0;
    blob_detector_params.minArea             = 10.0;
    blob_detector_params.minDistBetweenBlobs = 0; // 50?
    cv::SimpleBlobDetector blob_detector (blob_detector_params);

    blob_detector.detect (image_in, key_points);

    int i = 0;
    for (cv::KeyPoint point : key_points) {
        markers[i] = point;
        ++i;
    }

    cv::drawKeypoints (image_in, key_points, image_out);
    return image_out;
}

/*    cv::findContours (image_in, contours, hierarchy, CV_RETR_TREE,
 CV_CHAIN_APPROX_SIMPLE);

  cv::Mat drawing = cv::Mat::zeros (image_in.size (), CV_8UC3);
  for (unsigned int i = 0; i < contours.size (); i++) {
      cv::Scalar color =
      cv::Scalar (rng.uniform (0, 255), rng.uniform (0, 255), rng.uniform
 (0, 255));
      cv::drawContours (drawing, contours, i, color, 2, 8, hierarchy, 0);
  }

  return drawing;*/

/*
  // blob detection creation
    cv::SimpleBlobDetector::Params blob_detector_params;
    blob_detector_params.filterByArea        = true;
    blob_detector_params.maxArea             = 10000.0;
    blob_detector_params.minArea             = 10.0;
    blob_detector_params.minDistBetweenBlobs = 5.0; // 50?
    cv::SimpleBlobDetector blob_detector (blob_detector_params);

    blob_detector.detect (image_in, key_points);

    int i = 0;
    for (cv::KeyPoint point : key_points) {
        markers[i] = point;
        ++i;
    }

    cv::drawKeypoints (image_in, key_points, image_out);
*/
<commit_msg>change segmentation to otsus threshold only<commit_after>#include "vision_methods.hpp"
//#include <oepncv2/features2d.hpp>
#include <opencv2/opencv.hpp>

vision_methods::vision_methods () {
}

vision_methods::~vision_methods () {
}

cv::Mat vision_methods::preprocessing (const cv::Mat& image_in) {
    cv::Mat image_out;
    cvtColor (image_in, image_out, CV_BGR2GRAY);
    cv::GaussianBlur (image_out, image_out, cv::Size (_ksize_x, _ksize_y), _sigma_x, _sigma_y);
    return image_out;
}

cv::Mat vision_methods::segmentation (const cv::Mat& image_in) {
    cv::Mat image_out;

    cv::threshold (image_in, image_out, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

    return image_out;
}

cv::Mat vision_methods::extraction (const cv::Mat& image_in,
std::map<unsigned int, cv::KeyPoint>& markers) {
    std::vector<cv::KeyPoint> key_points;
    cv::Mat image_out;

    // blob detection creation
    cv::SimpleBlobDetector::Params blob_detector_params;
    blob_detector_params.filterByArea = true;
    blob_detector_params.maxArea      = 10000.0;
    blob_detector_params.minArea      = 10.0;
    cv::SimpleBlobDetector blob_detector (blob_detector_params);

    blob_detector.detect (image_in, key_points);

    int i = 0;
    for (cv::KeyPoint point : key_points) {
        markers[i] = point;
        ++i;
    }

    cv::drawKeypoints (image_in, key_points, image_out);
    return image_out;
}

/*    std::vector<cv::Vec4i> hierarchy;
    cv::RNG rng;
    cv::findContours (image_in, contours, hierarchy, CV_RETR_TREE,
 CV_CHAIN_APPROX_SIMPLE);

  cv::Mat drawing = cv::Mat::zeros (image_in.size (), CV_8UC3);
  for (unsigned int i = 0; i < contours.size (); i++) {
      cv::Scalar color =
      cv::Scalar (rng.uniform (0, 255), rng.uniform (0, 255), rng.uniform
 (0, 255));
      cv::drawContours (drawing, contours, i, color, 2, 8, hierarchy, 0);
  }

  return drawing;*/

/*
  // blob detection creation
    cv::SimpleBlobDetector::Params blob_detector_params;
    blob_detector_params.filterByArea        = true;
    blob_detector_params.maxArea             = 10000.0;
    blob_detector_params.minArea             = 10.0;
    blob_detector_params.minDistBetweenBlobs = 5.0; // 50?
    cv::SimpleBlobDetector blob_detector (blob_detector_params);

    blob_detector.detect (image_in, key_points);

    int i = 0;
    for (cv::KeyPoint point : key_points) {
        markers[i] = point;
        ++i;
    }

    cv::drawKeypoints (image_in, key_points, image_out);
*/
<|endoftext|>


<commit_before>/**
 ** \file object/object-class.cc
 ** \brief Creation of the URBI object object.
 */

//#define ENABLE_DEBUG_TRACES
#include <libport/compiler.hh>
#include <libport/throw-exception.hh>
#include <libport/tokenizer.hh>
#include <boost/lexical_cast.hpp>

#include "parser/uparser.hh"
#include "kernel/userver.hh"
#include "kernel/uconnection.hh"

#include "runner/runner.hh"

#include "object/atom.hh"
#include "object/object-class.hh"
#include "object/object.hh"

namespace object
{
  rObject object_class;

  /*--------------------.
  | Object primitives.  |
  `--------------------*/

  static rObject
  object_class_clone (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    return clone(args[0]);
  }

  static rObject
  object_class_init (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    return args[0];
  }

  /// Send dumped self on the connection.
  /// args[1], if present, can be the tag to use.
  static rObject
  object_class_dump (runner::Runner& r, objects_type args)
  {
    // Second argument is the tag name.
    std::string tag;
    if (args.size() == 2)
    {
      FETCH_ARG(1, String);
      tag = arg1->value_get().name_get();
    }
    std::ostringstream os;
    args[0]->dump(os);
    //for now our best choice is to dump line by line in "system" messages.
    const std::string stream = os.str();
    boost::tokenizer< boost::char_separator<char> > tok =
      libport::make_tokenizer(stream, "\n");
    std::string system_header("*** ");
    BOOST_FOREACH(std::string line, tok)
      r.lobby_get()->value_get().connection.send (
	(system_header+line+"\n").c_str(), tag.c_str());
    return void_class;
  }

  static rObject
  object_echo(runner::Runner& r, objects_type args, bool is_echo)
  {
    // Second argument is the tag name.
    std::string tag;
    if (args.size() == 3)
    {
      FETCH_ARG(2, String);
      tag = arg2->value_get().name_get();
    }
    //special case for Strings
    if (is_echo && args[1]->kind_is(Object::kind_string))
    {
      r.lobby_get()->value_get().connection.send((std::string("*** ")
			   + std::string(VALUE(args[1], String))
			   + "\n").c_str(),
			   tag.c_str());
    }
    else
      r.lobby_get()->value_get().connection.send (args[1], tag.c_str(),
	is_echo?"*** ":"");
    return void_class;
  }

  /// Send pretty-printed args[1] to the connection.
  static rObject
  object_class_echo (runner::Runner& r, objects_type args)
  {
    return object_echo(r, args, true);
  }

  /// Send pretty-printed self on the connection.
  /// args[1], if present, can be the tag to use.
  static rObject
  object_class_print (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT_RANGE (1, 2);
    objects_type nargs;
    nargs.push_back(args[0]);
    nargs.insert(nargs.end(),  args.begin(), args.end());
    return object_echo(r, nargs, false);
  }

  /// Send pretty-printed self on the connection.
  /// args[1], if present, can be the tag to use.
  static rObject
  object_class_asString (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    std::ostringstream os;
    args[0]->print(os);
    return new String(libport::Symbol(os.str()));
  }

  /// Return the address of an object as a number, mostly
  /// for debugging purpose.

  static rObject
  object_class_uid (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    std::string str = (boost::format ("0x%x") % reinterpret_cast<long long> (args[0].get ())).str ();
    return new String (libport::Symbol (str));
  }

  static rObject
  object_class_sameAs(runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    return args[0]->slot_get((args[0] == args[1])
			     ? SYMBOL(true)
			     : SYMBOL(false));
  }

#define SERVER_FUNCTION(Function)					\
  static rObject							\
  object_class_ ## Function (runner::Runner&, objects_type args)	\
  {									\
    CHECK_ARG_COUNT (1);						\
    ::urbiserver->Function();						\
    return void_class;							\
  }

  SERVER_FUNCTION(reboot)
  SERVER_FUNCTION(shutdown)

#undef SERVER_FUNCTION

  static rObject
  object_class_sleep (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    FETCH_ARG(1, Float);
    libport::utime_t deadline =
      ::urbiserver->getTime() +
      static_cast<libport::utime_t>(arg1->value_get() * 1000.0);
    r.yield_until (deadline);
    return void_class;
  }

  static rObject
  object_class_time (runner::Runner&, objects_type)
  {
    return new Float(::urbiserver->getTime() / 1000.0);
  }

  static rObject
  execute_parsed (runner::Runner& r, UParser& p, UrbiException e)
  {
    ast::Nary errs;
    p.process_errors(&errs);
    errs.accept(r);

    if (ast::Nary* ast = p.ast_get())
    {
      ast->accept(r);
      //FIXME: deleting the tree now causes segv.
      //delete p.command_tree_get();
      //p.command_tree_set (0);
      return r.current_get();
    }
    else
      libport::throw_exception (e);
  }

  static rObject
  object_class_eval (runner::Runner& r, objects_type args)
  {
    FETCH_ARG(1, String);
    UParser p;
    p.process(arg1->value_get());
    return execute_parsed(r, p, PrimitiveError("",
	std::string("Error executing command.")));
  }

  static rObject
  object_class_searchFile (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    FETCH_ARG(1, String);

    UServer& s = r.lobby_get()->value_get().connection.server_get();
    try
    {
      return new String(libport::Symbol(
                          s.find_file(arg1->value_get ().name_get ())));
    }
    catch (libport::file_library::Not_found&)
    {
      boost::throw_exception(
        PrimitiveError("searchFile",
                       "Unable to find file: "
                       + arg1->value_get().name_get()));
      // Never reached
      assertion(false);
      return 0;
    }
  }

  static rObject
  object_class_loadFile (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    FETCH_ARG(1, String);

    std::string filename = arg1->value_get().name_get();

    if (!libport::path (filename).exists ())
      boost::throw_exception(PrimitiveError("loadFile",
                                            "No such file: " + filename));

    UParser p;

    p.process_file(arg1->value_get());
    return
      execute_parsed(r, p,
                     PrimitiveError("", //same message than k1
                                    "Error loading file: " + filename));
  }

  static rObject
  object_class_apply (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    FETCH_ARG (1, List);
    if (!arg1->value_get ().empty ())
      boost::throw_exception
	(PrimitiveError ("apply", "first argument must be an empty list"));
    return args[0];
  }

  static rObject
  object_class_fresh (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    return new String(libport::Symbol::fresh());
  }

  static rObject
  object_class_lobby (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    return r.lobby_get();
  }

  static rObject
  object_class_quit (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    r.lobby_get()->value_get().connection.close();
    return void_class;
  }

#define SERVER_SET_VAR(Function, Variable, Value)					\
  static rObject							\
  object_class_ ## Function (runner::Runner&, objects_type args)	\
  {									\
    CHECK_ARG_COUNT (1);						\
    ::urbiserver->Variable = Value;					\
    return void_class;							\
  }

  SERVER_SET_VAR(debugoff, debugOutput, false)
  SERVER_SET_VAR(debugon, debugOutput, true)
  SERVER_SET_VAR(stopall, stopall, true)

#undef SERVER_SET_VAR

  /*---------.
  | Protos.  |
  `---------*/

  /// Adding or removing protos. \a Verb is "add" or "remove".
#define CHANGE_PARENTS(Verb)						\
  static rObject							\
  object_class_ ## Verb ## Proto (runner::Runner&, objects_type args)	\
  {									\
    CHECK_ARG_COUNT(2);							\
    args[0]->proto_ ## Verb (args[1]);					\
    return args[0];							\
  }

  /// Add a proto.
  CHANGE_PARENTS(add);
  /// Remove a proto.
  CHANGE_PARENTS(remove);
#undef CHANGE_PARENTS

  /// Get protos' list.
  static rObject
  object_class_protos (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(1);
    rObject obj = args[0];

    object::list_traits::type l;
    BOOST_FOREACH (const rObject o, obj->protos_get())
      l.push_back(o);

    return new object::List(l);
  }

  /*--------.
  | Slots.  |
  `--------*/

  /// List of slot names.
  static rObject
  object_class_slotNames (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(1);
    rObject obj = args[0];

    object::list_traits::type l;
    BOOST_FOREACH (const Object::slot_type& p, obj->slots_get())
      l.push_back (new object::String (p.first));

    return new object::List (l);
  }

  /// Get a slot content.
  static rObject
  object_class_getSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(2);
    rObject obj = args[0];
    FETCH_ARG(1, String);
    return obj->slot_get(arg1->value_get());
  }

  static rObject
  object_class_getLazyLocalSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (4);

    FETCH_ARG (1, String);
    Object::key_type slot_name = arg1->value_get ();

    // If the slot already exists, return its content.
    rObject slot = args[0]->own_slot_get (slot_name, 0);
    if (slot)
      return slot;

    // The slot doesn't exist. Should we create it?
    if (IS_TRUE (args[3]))
      args[0]->slot_set (slot_name, args[2]);

    // Return the default value for this slot.
    return args[2];
  }

  /// Remove a slot.
  static rObject
  object_class_removeSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(2);
    rObject obj = args[0];
    FETCH_ARG(1, String);
    obj->slot_remove(arg1->value_get());
    return obj;
  }

   /// Locate a slot.
  static rObject
  object_class_locateSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(2);
    FETCH_ARG(1, String);

    rObject o = slot_locate(args[0], arg1->value_get());
    return o ? o : nil_class;
  }

  static rObject
  object_class_setSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (3);
    FETCH_ARG (1, String);
    args[0]->slot_set (arg1->value_get (), args[2]);
    return args[2];
  }

  static rObject
  object_class_updateSlot (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (3);
    FETCH_ARG (1, String);
    slot_update (r, args[0], arg1->value_get (), args[2]);
    return args[2];
  }

  static rObject
  object_class_makeScope (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    args[0]->locals_set (IS_TRUE (args[1]));
    return args[0];
  }

  static rObject
  object_class_isScope (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    return new Float (!!args[0]->locals_get ());
  }

  void
  object_class_initialize ()
  {
    /// \a Call gives the name of the C++ function, and \a Name that in Urbi.
#define DECLARE(Name)				\
    DECLARE_PRIMITIVE(object, Name)

    DECLARE(clone);
    DECLARE(init);

    DECLARE(protos);
    DECLARE(addProto);
    DECLARE(removeProto);

    DECLARE(slotNames);
    DECLARE(getLazyLocalSlot);
    DECLARE(getSlot);
    DECLARE(removeSlot);
    DECLARE(setSlot);
    DECLARE(updateSlot);
    DECLARE(locateSlot);
    DECLARE(makeScope);
    DECLARE(isScope);

    DECLARE(apply);

    DECLARE(asString);
    DECLARE(debugoff);
    DECLARE(debugon);
    DECLARE(dump);
    DECLARE(echo);
    DECLARE(eval);
    DECLARE(fresh);
    DECLARE(loadFile);
    DECLARE(lobby);
    DECLARE(print);
    DECLARE(quit);
    DECLARE(reboot);
    DECLARE(sameAs);
    DECLARE(searchFile);
    DECLARE(shutdown);
    DECLARE(sleep);
    DECLARE(stopall);
    DECLARE(time);
    DECLARE(uid);
#undef DECLARE
  }

}; // namespace object
<commit_msg>Sort.<commit_after>/**
 ** \file object/object-class.cc
 ** \brief Creation of the URBI object object.
 */

//#define ENABLE_DEBUG_TRACES
#include <libport/compiler.hh>
#include <libport/throw-exception.hh>
#include <libport/tokenizer.hh>
#include <boost/lexical_cast.hpp>

#include "parser/uparser.hh"
#include "kernel/userver.hh"
#include "kernel/uconnection.hh"

#include "runner/runner.hh"

#include "object/atom.hh"
#include "object/object-class.hh"
#include "object/object.hh"

namespace object
{
  rObject object_class;

  /*--------------------.
  | Object primitives.  |
  `--------------------*/

  static rObject
  object_class_clone (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    return clone(args[0]);
  }

  static rObject
  object_class_init (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    return args[0];
  }

  /// Send dumped self on the connection.
  /// args[1], if present, can be the tag to use.
  static rObject
  object_class_dump (runner::Runner& r, objects_type args)
  {
    // Second argument is the tag name.
    std::string tag;
    if (args.size() == 2)
    {
      FETCH_ARG(1, String);
      tag = arg1->value_get().name_get();
    }
    std::ostringstream os;
    args[0]->dump(os);
    //for now our best choice is to dump line by line in "system" messages.
    const std::string stream = os.str();
    boost::tokenizer< boost::char_separator<char> > tok =
      libport::make_tokenizer(stream, "\n");
    std::string system_header("*** ");
    BOOST_FOREACH(std::string line, tok)
      r.lobby_get()->value_get().connection.send (
	(system_header+line+"\n").c_str(), tag.c_str());
    return void_class;
  }

  static rObject
  object_echo(runner::Runner& r, objects_type args, bool is_echo)
  {
    // Second argument is the tag name.
    std::string tag;
    if (args.size() == 3)
    {
      FETCH_ARG(2, String);
      tag = arg2->value_get().name_get();
    }
    //special case for Strings
    if (is_echo && args[1]->kind_is(Object::kind_string))
    {
      r.lobby_get()->value_get().connection.send((std::string("*** ")
			   + std::string(VALUE(args[1], String))
			   + "\n").c_str(),
			   tag.c_str());
    }
    else
      r.lobby_get()->value_get().connection.send (args[1], tag.c_str(),
	is_echo?"*** ":"");
    return void_class;
  }

  /// Send pretty-printed args[1] to the connection.
  static rObject
  object_class_echo (runner::Runner& r, objects_type args)
  {
    return object_echo(r, args, true);
  }

  /// Send pretty-printed self on the connection.
  /// args[1], if present, can be the tag to use.
  static rObject
  object_class_print (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT_RANGE (1, 2);
    objects_type nargs;
    nargs.push_back(args[0]);
    nargs.insert(nargs.end(),  args.begin(), args.end());
    return object_echo(r, nargs, false);
  }

  /// Send pretty-printed self on the connection.
  /// args[1], if present, can be the tag to use.
  static rObject
  object_class_asString (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    std::ostringstream os;
    args[0]->print(os);
    return new String(libport::Symbol(os.str()));
  }

  /// Return the address of an object as a number, mostly
  /// for debugging purpose.

  static rObject
  object_class_uid (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    std::string str = (boost::format ("0x%x") % reinterpret_cast<long long> (args[0].get ())).str ();
    return new String (libport::Symbol (str));
  }

  static rObject
  object_class_sameAs(runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    return args[0]->slot_get((args[0] == args[1])
			     ? SYMBOL(true)
			     : SYMBOL(false));
  }

#define SERVER_FUNCTION(Function)					\
  static rObject							\
  object_class_ ## Function (runner::Runner&, objects_type args)	\
  {									\
    CHECK_ARG_COUNT (1);						\
    ::urbiserver->Function();						\
    return void_class;							\
  }

  SERVER_FUNCTION(reboot)
  SERVER_FUNCTION(shutdown)

#undef SERVER_FUNCTION

  static rObject
  object_class_sleep (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    FETCH_ARG(1, Float);
    libport::utime_t deadline =
      ::urbiserver->getTime() +
      static_cast<libport::utime_t>(arg1->value_get() * 1000.0);
    r.yield_until (deadline);
    return void_class;
  }

  static rObject
  object_class_time (runner::Runner&, objects_type)
  {
    return new Float(::urbiserver->getTime() / 1000.0);
  }

  static rObject
  execute_parsed (runner::Runner& r, UParser& p, UrbiException e)
  {
    ast::Nary errs;
    p.process_errors(&errs);
    errs.accept(r);

    if (ast::Nary* ast = p.ast_get())
    {
      ast->accept(r);
      //FIXME: deleting the tree now causes segv.
      //delete p.command_tree_get();
      //p.command_tree_set (0);
      return r.current_get();
    }
    else
      libport::throw_exception (e);
  }

  static rObject
  object_class_eval (runner::Runner& r, objects_type args)
  {
    FETCH_ARG(1, String);
    UParser p;
    p.process(arg1->value_get());
    return execute_parsed(r, p, PrimitiveError("",
	std::string("Error executing command.")));
  }

  static rObject
  object_class_searchFile (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    FETCH_ARG(1, String);

    UServer& s = r.lobby_get()->value_get().connection.server_get();
    try
    {
      return new String(libport::Symbol(
			  s.find_file(arg1->value_get ().name_get ())));
    }
    catch (libport::file_library::Not_found&)
    {
      boost::throw_exception(
	PrimitiveError("searchFile",
		       "Unable to find file: "
		       + arg1->value_get().name_get()));
      // Never reached
      assertion(false);
      return 0;
    }
  }

  static rObject
  object_class_loadFile (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    FETCH_ARG(1, String);

    std::string filename = arg1->value_get().name_get();

    if (!libport::path (filename).exists ())
      boost::throw_exception(PrimitiveError("loadFile",
					    "No such file: " + filename));

    UParser p;

    p.process_file(arg1->value_get());
    return
      execute_parsed(r, p,
		     PrimitiveError("", //same message than k1
				    "Error loading file: " + filename));
  }

  static rObject
  object_class_apply (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    FETCH_ARG (1, List);
    if (!arg1->value_get ().empty ())
      boost::throw_exception
	(PrimitiveError ("apply", "first argument must be an empty list"));
    return args[0];
  }

  static rObject
  object_class_fresh (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    return new String(libport::Symbol::fresh());
  }

  static rObject
  object_class_lobby (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    return r.lobby_get();
  }

  static rObject
  object_class_quit (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    r.lobby_get()->value_get().connection.close();
    return void_class;
  }

#define SERVER_SET_VAR(Function, Variable, Value)					\
  static rObject							\
  object_class_ ## Function (runner::Runner&, objects_type args)	\
  {									\
    CHECK_ARG_COUNT (1);						\
    ::urbiserver->Variable = Value;					\
    return void_class;							\
  }

  SERVER_SET_VAR(debugoff, debugOutput, false)
  SERVER_SET_VAR(debugon, debugOutput, true)
  SERVER_SET_VAR(stopall, stopall, true)

#undef SERVER_SET_VAR

  /*---------.
  | Protos.  |
  `---------*/

  /// Adding or removing protos. \a Verb is "add" or "remove".
#define CHANGE_PARENTS(Verb)						\
  static rObject							\
  object_class_ ## Verb ## Proto (runner::Runner&, objects_type args)	\
  {									\
    CHECK_ARG_COUNT(2);							\
    args[0]->proto_ ## Verb (args[1]);					\
    return args[0];							\
  }

  /// Add a proto.
  CHANGE_PARENTS(add);
  /// Remove a proto.
  CHANGE_PARENTS(remove);
#undef CHANGE_PARENTS

  /// Get protos' list.
  static rObject
  object_class_protos (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(1);
    rObject obj = args[0];

    object::list_traits::type l;
    BOOST_FOREACH (const rObject o, obj->protos_get())
      l.push_back(o);

    return new object::List(l);
  }

  /*--------.
  | Slots.  |
  `--------*/

  /// List of slot names.
  static rObject
  object_class_slotNames (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(1);
    rObject obj = args[0];

    object::list_traits::type l;
    BOOST_FOREACH (const Object::slot_type& p, obj->slots_get())
      l.push_back (new object::String (p.first));

    return new object::List (l);
  }

  /// Get a slot content.
  static rObject
  object_class_getSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(2);
    rObject obj = args[0];
    FETCH_ARG(1, String);
    return obj->slot_get(arg1->value_get());
  }

  static rObject
  object_class_getLazyLocalSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (4);

    FETCH_ARG (1, String);
    Object::key_type slot_name = arg1->value_get ();

    // If the slot already exists, return its content.
    rObject slot = args[0]->own_slot_get (slot_name, 0);
    if (slot)
      return slot;

    // The slot doesn't exist. Should we create it?
    if (IS_TRUE (args[3]))
      args[0]->slot_set (slot_name, args[2]);

    // Return the default value for this slot.
    return args[2];
  }

  /// Remove a slot.
  static rObject
  object_class_removeSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(2);
    rObject obj = args[0];
    FETCH_ARG(1, String);
    obj->slot_remove(arg1->value_get());
    return obj;
  }

   /// Locate a slot.
  static rObject
  object_class_locateSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(2);
    FETCH_ARG(1, String);

    rObject o = slot_locate(args[0], arg1->value_get());
    return o ? o : nil_class;
  }

  static rObject
  object_class_setSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (3);
    FETCH_ARG (1, String);
    args[0]->slot_set (arg1->value_get (), args[2]);
    return args[2];
  }

  static rObject
  object_class_updateSlot (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (3);
    FETCH_ARG (1, String);
    slot_update (r, args[0], arg1->value_get (), args[2]);
    return args[2];
  }

  static rObject
  object_class_makeScope (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    args[0]->locals_set (IS_TRUE (args[1]));
    return args[0];
  }

  static rObject
  object_class_isScope (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    return new Float (!!args[0]->locals_get ());
  }

  void
  object_class_initialize ()
  {
    /// \a Call gives the name of the C++ function, and \a Name that in Urbi.
#define DECLARE(Name)				\
    DECLARE_PRIMITIVE(object, Name)

    DECLARE(addProto);
    DECLARE(apply);
    DECLARE(asString);
    DECLARE(clone);
    DECLARE(debugoff);
    DECLARE(debugon);
    DECLARE(dump);
    DECLARE(echo);
    DECLARE(eval);
    DECLARE(fresh);
    DECLARE(getLazyLocalSlot);
    DECLARE(getSlot);
    DECLARE(init);
    DECLARE(isScope);
    DECLARE(loadFile);
    DECLARE(lobby);
    DECLARE(locateSlot);
    DECLARE(makeScope);
    DECLARE(print);
    DECLARE(protos);
    DECLARE(quit);
    DECLARE(reboot);
    DECLARE(removeProto);
    DECLARE(removeSlot);
    DECLARE(sameAs);
    DECLARE(searchFile);
    DECLARE(setSlot);
    DECLARE(shutdown);
    DECLARE(sleep);
    DECLARE(slotNames);
    DECLARE(stopall);
    DECLARE(time);
    DECLARE(uid);
    DECLARE(updateSlot);
#undef DECLARE
  }

}; // namespace object
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007-2011, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/**
 ** \file urbi/object/object.class.cc
 ** \brief Creation of the Urbi object object.
 */

#include <libport/bind.hh>
#include <libport/format.hh>

#include <libport/compiler.hh>
#include <libport/containers.hh>
#include <libport/escape.hh>
#include <libport/foreach.hh>
#include <libport/tokenizer.hh>

#include <kernel/uconnection.hh>
#include <kernel/userver.hh>
#include <object/object-class.hh>
#include <object/symbols.hh>
#include <runner/runner.hh>
#include <urbi/object/cxx-primitive.hh>
#include <urbi/object/dictionary.hh>
#include <urbi/object/event.hh>
#include <urbi/object/float.hh>
#include <urbi/object/global.hh>
#include <urbi/object/hash.hh>
#include <urbi/object/list.hh>
#include <urbi/object/object.hh>
#include <urbi/object/string.hh>
#include <urbi/runner/raise.hh>

namespace urbi
{
  namespace object
  {
    /*--------------------.
    | Object primitives.  |
    `--------------------*/

    static rObject
    object_class_clone(const objects_type& args)
    {
      check_arg_count(args.size() - 1, 0);
      return args[0]->clone();
    }

    static rObject
    object_class_init(const objects_type& args)
    {
      check_arg_count(args.size() - 1, 0);
      return args[0];
    }

    /// Send dumped self on the connection.
    /// args[1], if present, can be the tag to use.
    static rObject
    object_class_dump(const objects_type& args)
    {
      runner::Runner& r = ::kernel::runner();

      check_arg_count(args.size() - 1, 1, 2);

      // Second argument is max depth.
      int depth_max = 0;
      if (2 <= args.size())
      {
        const rFloat& arg1 = from_urbi<rFloat>(args[1], 1u);
        try
        {
          depth_max = libport::numeric_cast<int>(arg1->value_get());
        }
        catch (libport::bad_numeric_cast& ue)
        {
          runner::raise_bad_integer_error(arg1->value_get());
        }
      }

      // Third argument is the tag name.
      std::string tag;
      if (3 <= args.size())
      {
        const rString& arg2 = from_urbi<rString>(args[2], 2u);
        aver(arg2);
        tag = arg2->value_get();
      }

      // Do not use libport::lines on os.str().
      std::string dump;
      {
        std::ostringstream os;
        args[0]->dump(os, depth_max);
        dump = os.str();
      }
      // For now our best choice is to dump line by line in "system" messages.
      const std::string system_header("*** ");
      foreach (const std::string& line, libport::lines(dump))
        r.send_message(tag, system_header + line);
      return void_class;
    }

    /// Return the address of an object as a number, mostly
    /// for debugging purpose.
    static rObject
    object_class_uid(const objects_type& args)
    {
      static boost::format uid("0x%x");
      check_arg_count(args.size() - 1, 0);
      return
        new String(str(uid % reinterpret_cast<long long>(args[0].get())));
    }

    /// Structural equality
    static rObject
    object_class_EQ_EQ(const objects_type& args)
    {
      // Unless overridden, structural equality is physical equality.
      check_arg_count(args.size() - 1, 1);
      return args[0]->call(SYMBOL(EQ_EQ_EQ), args[1]);
    }

    /// Physical equality
    static rObject
    object_class_EQ_EQ_EQ(const objects_type& args)
    {
      check_arg_count(args.size() - 1, 1);
      return to_boolean(args[0] == args[1]);
    }

    static rObject
    object_class_apply(rObject self, const objects_type& args)
    {
      unsigned nargs = args.size();
      if (nargs != 1)
        runner::raise_arity_error(nargs, 1);
      return self;
    }

    static rObject
    object_class_callMessage (rObject target, rObject call_message)
    {
      DECLARE_LOCATION_FILE;
      runner::Runner& r = ::kernel::runner();

      // We need to set the 'code' slot: make a copy of the call message.
      const rObject& message = call_message->slot_get(SYMBOL(message));
      const libport::Symbol msg(from_urbi<std::string>(message));
      const rObject& code = target->slot_get(msg);
      call_message->slot_update(SYMBOL(code), code);
      call_message->slot_update(SYMBOL(target), target);
      // FIXME: Sanity checks on the call message are probably required
      return r.apply_call_message(code, msg, call_message, LOCATION_HERE);
    }

    /*---------.
    | Protos.  |
    `---------*/

    /// Get protos' list.
    static rObject
    object_class_protos (const objects_type& args)
    {
      check_arg_count(args.size() - 1, 0);
      return args[0]->urbi_protos_get ();
    }

    /// Add a prototype
    static bool
    proto_add(List::value_type& protos, const rObject& proto)
    {
      protos.push_back(proto);
      return false;
    }

    /// Recursively get protos list
    static rObject
    object_class_allProtos(const objects_type& args)
    {
      check_arg_count(args.size() - 1, 0);
      List::value_type res;
      for_all_protos(args[0], boost::bind(&proto_add, boost::ref(res), _1));
      return new List(res);
    }

    /*--------.
    | Slots.  |
    `--------*/

    template <typename F>
    static inline void for_all_slot_names(const rObject& o, F f)
    {
      for (Object::slots_implem::iterator slot = o->slots_get().begin(o.get());
           slot != o->slots_get().end(o.get());
           ++slot)
        f(slot->first.second);
    }

    static void
    add_as_rString(List::value_type& l, libport::Symbol slot_name)
    {
      l.push_back(new String(slot_name));
    }

    /// List of slot names.
    static rObject
    object_class_localSlotNames(const objects_type& args)
    {
      check_arg_count(args.size() - 1, 0);
      const rObject& obj = args[0];

      List::value_type l;
      for_all_slot_names(obj, boost::bind(&add_as_rString, boost::ref(l), _1));
      return new List(l);
    }

    /// Recursive list of slot names.
    static void
    maybe_add(std::vector<libport::Symbol>& control, List::value_type& l,
              libport::Symbol slot_name)
    {
      if (!libport::has(control, slot_name))
      {
        control.push_back(slot_name);
        l.push_back(new String(slot_name));
      }
    }

    static rObject
    object_class_slotNames(const objects_type& args)
    {
      check_arg_count(args.size() - 1, 0);
      std::vector<libport::Symbol> slot_names;
      List::value_type res;
      objects_type protos =
        object_class_allProtos(args)->as<List>()->value_get();
      foreach (const rObject& proto, protos)
      {
        for_all_slot_names(proto, boost::bind(&maybe_add,
                                              boost::ref(slot_names),
                                              boost::ref(res),
                                              _1));
      }
      return new List(res);
    }

    static bool
    object_class_isA(rObject self, rObject proto)
    {
      return is_a(self, proto);
    }

    static bool
    object_class_hasLocalSlot(rObject self, libport::Symbol slot)
    {
      return self->local_slot_get(slot);
    }

#define OPERATOR(Name)                                          \
    static rObject                                              \
    object_class_ ## Name ## _EQ(rObject lhs, rObject rhs)      \
    {                                                           \
      return lhs->call(SYMBOL_(Name), rhs);                     \
    }

    OPERATOR(CARET)
    OPERATOR(MINUS)
    OPERATOR(PERCENT)
    OPERATOR(PLUS)
    OPERATOR(SLASH)
    OPERATOR(STAR)
#undef OPERATOR

    static rObject
    object_class_PLUS_PLUS(rObject lhs)
    {
      static rObject one = to_urbi(1);
      return lhs->call(SYMBOL(PLUS_EQ), one);
    }

    static rObject
    object_class_MINUS_MINUS(rObject lhs)
    {
      static rObject one = to_urbi(1);
      return lhs->call(SYMBOL(MINUS_EQ), one);
    }

    void
    object_class_initialize()
    {
      Object::proto->slot_set(SYMBOL(isA),
                              primitive(object_class_isA));
      Object::proto->slot_set(SYMBOL(hasLocalSlot),
                              primitive(&object_class_hasLocalSlot));

#define DECLARE(Name)                                                   \
      Object::proto->slot_set(SYMBOL_(Name),                            \
                              new Primitive(object_class_##Name),       \
                              true)                                     \

      DECLARE(EQ_EQ);
      DECLARE(EQ_EQ_EQ);
      DECLARE(allProtos);
      DECLARE(clone);
      DECLARE(dump);
      DECLARE(init);
      DECLARE(localSlotNames);
      DECLARE(protos);
      DECLARE(slotNames);
      DECLARE(uid);
#undef DECLARE

#define DECLARE(Name, Code)                                             \
      Object::proto->slot_set(SYMBOL_(Name), primitive(Code))

      DECLARE(CARET_EQ           , object_class_CARET_EQ);
      DECLARE(MINUS_EQ           , object_class_MINUS_EQ);
      DECLARE(MINUS_MINUS        , object_class_MINUS_MINUS);
      DECLARE(PERCENT_EQ         , object_class_PERCENT_EQ);
      DECLARE(PLUS_EQ            , object_class_PLUS_EQ);
      DECLARE(PLUS_PLUS          , object_class_PLUS_PLUS);
      DECLARE(SLASH_EQ           , object_class_SLASH_EQ);
      DECLARE(STAR_EQ            , object_class_STAR_EQ);
      DECLARE(apply              , object_class_apply);
      DECLARE(asBool             , &Object::as_bool);
      DECLARE(asPrintable        , &Object::asPrintable);
      DECLARE(asToplevelPrintable, &Object::asToplevelPrintable);
      DECLARE(callMessage        , object_class_callMessage);
      DECLARE(changed            , &Object::changed_get);
      DECLARE(createSlot         , &Object::urbi_createSlot);
      DECLARE(getLocalSlot       , &Object::getLocalSlot);
      DECLARE(getProperty        , &Object::property_get);
      typedef rObject (Object::*get_slot_type)(Object::key_type);
      DECLARE(getSlot            ,
              static_cast<get_slot_type>(&Object::getSlot));
      DECLARE(hasProperty        , &Object::property_has);
      DECLARE(hasSlot            , &Object::slot_has);
      DECLARE(locateSlot         , &Object::urbi_locateSlot);
      DECLARE(properties         , &Object::urbi_properties);
      DECLARE(removeProperty     , &Object::property_remove);
      DECLARE(removeLocalSlot    , &Object::urbi_removeLocalSlot);
      DECLARE(removeSlot         , &Object::urbi_removeSlot);
      DECLARE(setConstSlot       , &Object::urbi_setConstSlot);
      DECLARE(setProperty        , &Object::property_set);
      typedef rObject (Object::*set_slot_type)(Object::key_type,
                                               const rObject&);
      DECLARE(setSlot            ,
              static_cast<set_slot_type>(&Object::setSlot));
      DECLARE(updateSlot         , &Object::urbi_updateSlot);
#undef DECLARE

      Object::proto->bind(SYMBOL(addProto),     &Object::addProto);
      Object::proto->bind(SYMBOL(hash),         &Object::hash);
      Object::proto->bind(SYMBOL(removeProto),  &Object::removeProto);
    }
  }; // namespace object
}
<commit_msg>Add Object.refCount.<commit_after>/*
 * Copyright (C) 2007-2011, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/**
 ** \file urbi/object/object.class.cc
 ** \brief Creation of the Urbi object object.
 */

#include <libport/bind.hh>
#include <libport/format.hh>

#include <libport/compiler.hh>
#include <libport/containers.hh>
#include <libport/escape.hh>
#include <libport/foreach.hh>
#include <libport/tokenizer.hh>

#include <kernel/uconnection.hh>
#include <kernel/userver.hh>
#include <object/object-class.hh>
#include <object/symbols.hh>
#include <runner/runner.hh>
#include <urbi/object/cxx-primitive.hh>
#include <urbi/object/dictionary.hh>
#include <urbi/object/event.hh>
#include <urbi/object/float.hh>
#include <urbi/object/global.hh>
#include <urbi/object/hash.hh>
#include <urbi/object/list.hh>
#include <urbi/object/object.hh>
#include <urbi/object/string.hh>
#include <urbi/runner/raise.hh>

namespace urbi
{
  namespace object
  {
    /*--------------------.
    | Object primitives.  |
    `--------------------*/

    static rObject
    object_class_clone(const objects_type& args)
    {
      check_arg_count(args.size() - 1, 0);
      return args[0]->clone();
    }

    static rObject
    object_class_init(const objects_type& args)
    {
      check_arg_count(args.size() - 1, 0);
      return args[0];
    }

    /// Send dumped self on the connection.
    /// args[1], if present, can be the tag to use.
    static rObject
    object_class_dump(const objects_type& args)
    {
      runner::Runner& r = ::kernel::runner();

      check_arg_count(args.size() - 1, 1, 2);

      // Second argument is max depth.
      int depth_max = 0;
      if (2 <= args.size())
      {
        const rFloat& arg1 = from_urbi<rFloat>(args[1], 1u);
        try
        {
          depth_max = libport::numeric_cast<int>(arg1->value_get());
        }
        catch (libport::bad_numeric_cast& ue)
        {
          runner::raise_bad_integer_error(arg1->value_get());
        }
      }

      // Third argument is the tag name.
      std::string tag;
      if (3 <= args.size())
      {
        const rString& arg2 = from_urbi<rString>(args[2], 2u);
        aver(arg2);
        tag = arg2->value_get();
      }

      // Do not use libport::lines on os.str().
      std::string dump;
      {
        std::ostringstream os;
        args[0]->dump(os, depth_max);
        dump = os.str();
      }
      // For now our best choice is to dump line by line in "system" messages.
      const std::string system_header("*** ");
      foreach (const std::string& line, libport::lines(dump))
        r.send_message(tag, system_header + line);
      return void_class;
    }

    /// Return the address of an object as a number, mostly
    /// for debugging purpose.
    static rObject
    object_class_uid(const objects_type& args)
    {
      static boost::format uid("0x%x");
      check_arg_count(args.size() - 1, 0);
      return
        new String(str(uid % reinterpret_cast<long long>(args[0].get())));
    }

    /// Structural equality
    static rObject
    object_class_EQ_EQ(const objects_type& args)
    {
      // Unless overridden, structural equality is physical equality.
      check_arg_count(args.size() - 1, 1);
      return args[0]->call(SYMBOL(EQ_EQ_EQ), args[1]);
    }

    /// Physical equality
    static rObject
    object_class_EQ_EQ_EQ(const objects_type& args)
    {
      check_arg_count(args.size() - 1, 1);
      return to_boolean(args[0] == args[1]);
    }

    static rObject
    object_class_apply(rObject self, const objects_type& args)
    {
      unsigned nargs = args.size();
      if (nargs != 1)
        runner::raise_arity_error(nargs, 1);
      return self;
    }

    static rObject
    object_class_callMessage (rObject target, rObject call_message)
    {
      DECLARE_LOCATION_FILE;
      runner::Runner& r = ::kernel::runner();

      // We need to set the 'code' slot: make a copy of the call message.
      const rObject& message = call_message->slot_get(SYMBOL(message));
      const libport::Symbol msg(from_urbi<std::string>(message));
      const rObject& code = target->slot_get(msg);
      call_message->slot_update(SYMBOL(code), code);
      call_message->slot_update(SYMBOL(target), target);
      // FIXME: Sanity checks on the call message are probably required
      return r.apply_call_message(code, msg, call_message, LOCATION_HERE);
    }

    /*---------.
    | Protos.  |
    `---------*/

    /// Get protos' list.
    static rObject
    object_class_protos (const objects_type& args)
    {
      check_arg_count(args.size() - 1, 0);
      return args[0]->urbi_protos_get ();
    }

    /// Add a prototype
    static bool
    proto_add(List::value_type& protos, const rObject& proto)
    {
      protos.push_back(proto);
      return false;
    }

    /// Recursively get protos list
    static rObject
    object_class_allProtos(const objects_type& args)
    {
      check_arg_count(args.size() - 1, 0);
      List::value_type res;
      for_all_protos(args[0], boost::bind(&proto_add, boost::ref(res), _1));
      return new List(res);
    }

    /*--------.
    | Slots.  |
    `--------*/

    template <typename F>
    static inline void for_all_slot_names(const rObject& o, F f)
    {
      for (Object::slots_implem::iterator slot = o->slots_get().begin(o.get());
           slot != o->slots_get().end(o.get());
           ++slot)
        f(slot->first.second);
    }

    static void
    add_as_rString(List::value_type& l, libport::Symbol slot_name)
    {
      l.push_back(new String(slot_name));
    }

    /// List of slot names.
    static rObject
    object_class_localSlotNames(const objects_type& args)
    {
      check_arg_count(args.size() - 1, 0);
      const rObject& obj = args[0];

      List::value_type l;
      for_all_slot_names(obj, boost::bind(&add_as_rString, boost::ref(l), _1));
      return new List(l);
    }

    /// Recursive list of slot names.
    static void
    maybe_add(std::vector<libport::Symbol>& control, List::value_type& l,
              libport::Symbol slot_name)
    {
      if (!libport::has(control, slot_name))
      {
        control.push_back(slot_name);
        l.push_back(new String(slot_name));
      }
    }

    static rObject
    object_class_slotNames(const objects_type& args)
    {
      check_arg_count(args.size() - 1, 0);
      std::vector<libport::Symbol> slot_names;
      List::value_type res;
      objects_type protos =
        object_class_allProtos(args)->as<List>()->value_get();
      foreach (const rObject& proto, protos)
      {
        for_all_slot_names(proto, boost::bind(&maybe_add,
                                              boost::ref(slot_names),
                                              boost::ref(res),
                                              _1));
      }
      return new List(res);
    }

    static bool
    object_class_isA(rObject self, rObject proto)
    {
      return is_a(self, proto);
    }

    static bool
    object_class_hasLocalSlot(rObject self, libport::Symbol slot)
    {
      return self->local_slot_get(slot);
    }

#define OPERATOR(Name)                                          \
    static rObject                                              \
    object_class_ ## Name ## _EQ(rObject lhs, rObject rhs)      \
    {                                                           \
      return lhs->call(SYMBOL_(Name), rhs);                     \
    }

    OPERATOR(CARET)
    OPERATOR(MINUS)
    OPERATOR(PERCENT)
    OPERATOR(PLUS)
    OPERATOR(SLASH)
    OPERATOR(STAR)
#undef OPERATOR

    static rObject
    object_class_PLUS_PLUS(rObject lhs)
    {
      static rObject one = to_urbi(1);
      return lhs->call(SYMBOL(PLUS_EQ), one);
    }

    static rObject
    object_class_MINUS_MINUS(rObject lhs)
    {
      static rObject one = to_urbi(1);
      return lhs->call(SYMBOL(MINUS_EQ), one);
    }

    void
    object_class_initialize()
    {
      Object::proto->slot_set(SYMBOL(isA),
                              primitive(object_class_isA));
      Object::proto->slot_set(SYMBOL(hasLocalSlot),
                              primitive(&object_class_hasLocalSlot));

#define DECLARE(Name)                                                   \
      Object::proto->slot_set(SYMBOL_(Name),                            \
                              new Primitive(object_class_##Name),       \
                              true)                                     \

      DECLARE(EQ_EQ);
      DECLARE(EQ_EQ_EQ);
      DECLARE(allProtos);
      DECLARE(clone);
      DECLARE(dump);
      DECLARE(init);
      DECLARE(localSlotNames);
      DECLARE(protos);
      DECLARE(slotNames);
      DECLARE(uid);
#undef DECLARE

#define DECLARE(Name, Code)                                             \
      Object::proto->slot_set(SYMBOL_(Name), primitive(Code))

      DECLARE(CARET_EQ           , object_class_CARET_EQ);
      DECLARE(MINUS_EQ           , object_class_MINUS_EQ);
      DECLARE(MINUS_MINUS        , object_class_MINUS_MINUS);
      DECLARE(PERCENT_EQ         , object_class_PERCENT_EQ);
      DECLARE(PLUS_EQ            , object_class_PLUS_EQ);
      DECLARE(PLUS_PLUS          , object_class_PLUS_PLUS);
      DECLARE(SLASH_EQ           , object_class_SLASH_EQ);
      DECLARE(STAR_EQ            , object_class_STAR_EQ);
      DECLARE(apply              , object_class_apply);
      DECLARE(asBool             , &Object::as_bool);
      DECLARE(asPrintable        , &Object::asPrintable);
      DECLARE(asToplevelPrintable, &Object::asToplevelPrintable);
      DECLARE(callMessage        , object_class_callMessage);
      DECLARE(changed            , &Object::changed_get);
      DECLARE(createSlot         , &Object::urbi_createSlot);
      DECLARE(getLocalSlot       , &Object::getLocalSlot);
      DECLARE(getProperty        , &Object::property_get);
      typedef rObject (Object::*get_slot_type)(Object::key_type);
      DECLARE(getSlot            ,
              static_cast<get_slot_type>(&Object::getSlot));
      DECLARE(hasProperty        , &Object::property_has);
      DECLARE(hasSlot            , &Object::slot_has);
      DECLARE(locateSlot         , &Object::urbi_locateSlot);
      DECLARE(properties         , &Object::urbi_properties);
      DECLARE(removeProperty     , &Object::property_remove);
      DECLARE(removeLocalSlot    , &Object::urbi_removeLocalSlot);
      DECLARE(removeSlot         , &Object::urbi_removeSlot);
      DECLARE(setConstSlot       , &Object::urbi_setConstSlot);
      DECLARE(setProperty        , &Object::property_set);
      typedef rObject (Object::*set_slot_type)(Object::key_type,
                                               const rObject&);
      DECLARE(setSlot            ,
              static_cast<set_slot_type>(&Object::setSlot));
      DECLARE(updateSlot         , &Object::urbi_updateSlot);
#undef DECLARE

      Object::proto->bind(SYMBOL(refCount),     &Object::counter_get);
      Object::proto->bind(SYMBOL(addProto),     &Object::addProto);
      Object::proto->bind(SYMBOL(hash),         &Object::hash);
      Object::proto->bind(SYMBOL(removeProto),  &Object::removeProto);
    }
  }; // namespace object
}
<|endoftext|>


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

#include "MeshNode.h"

#include "../wrapper/WrapHelper.h"
#include "../base/Logger.h"
#include "../base/Exception.h"

#include "NodeDefinition.h"
#include "VectorNode.h"
#include "Player.h"

#include <cstdlib>
#include <string>
#include <iostream>

using namespace std;
using namespace boost::python;

namespace avg {

NodeDefinition MeshNode::createDefinition()
{
    vector<DPoint> vVert;
    vector<DPoint> vTex;
    vector<IntTriple> vTriangle;

    return NodeDefinition("mesh", (NodeBuilder)MeshNode::buildNode<MeshNode>)
        .extendDefinition(VectorNode::createDefinition())
        .addArg(Arg<vector<DPoint> >("vertexcoords", vVert, false, offsetof(MeshNode, m_VertexCoords)))
        .addArg(Arg<vector<DPoint> >("texcoords", vTex, false, offsetof(MeshNode, m_TexCoords)))
        .addArg(Arg<vector<IntTriple> >("triangles", vTriangle, false, offsetof(MeshNode, m_Triangles)))
        ;
}

MeshNode::MeshNode(const ArgList& Args)
    : VectorNode(Args)
{
    Args.setMembers(this);
    isValid(m_TexCoords);
}

MeshNode::~MeshNode()
{
}

void MeshNode::isValid(const vector<DPoint>& coords)
{
    if (coords.size() != m_VertexCoords.size()) {
        throw(Exception(AVG_ERR_OUT_OF_RANGE,
                "Coordinates Out of Range"));
    }
}

const vector<DPoint>& MeshNode::getVertexCoords() const
{
    return m_VertexCoords;
}

void MeshNode::setVertexCoords(const vector<DPoint>& coords)
{
    isValid(coords);
    m_VertexCoords = coords;
    setDrawNeeded(false);
}

const vector<DPoint>& MeshNode::getTexCoords() const
{
    return m_TexCoords;
}

void MeshNode::setTexCoords(const vector<DPoint>& coords)
{
    isValid(coords);
    m_TexCoords = coords;
    setDrawNeeded(true);
}

const vector<IntTriple>& MeshNode::getTriangles() const
{
    return m_Triangles;
}

void MeshNode::setTriangles(const vector<IntTriple>& triangles)
{
    for (unsigned int i = 0; i < triangles.size(); i++) {

        if( static_cast<unsigned int>(triangles[i].x) < 0 ||
            static_cast<unsigned int>(triangles[i].y) < 0 ||
            static_cast<unsigned int>(triangles[i].z) < 0){
            throw(Exception(AVG_ERR_OUT_OF_RANGE,
                "Triangle Index Out of Range < 0"));
        }

        if( static_cast<unsigned int>(triangles[i].x) > triangles.size() ||
            static_cast<unsigned int>(triangles[i].y) > triangles.size() ||
            static_cast<unsigned int>(triangles[i].z) > triangles.size()){
            throw(Exception(AVG_ERR_OUT_OF_RANGE,
                "Triangle Index Out of Range > max triangles"));
        }
    }
    m_Triangles = triangles;
}

int MeshNode::getNumVertexes()
{
    int numVertex = getNumDifferentPts(m_VertexCoords);
    return numVertex;
}

int MeshNode::getNumIndexes()
{
    int numTriangles = m_Triangles.size()*3;
    return numTriangles;
}

void MeshNode::calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
{
    for (unsigned int i = 0; i < m_VertexCoords.size(); i++) {
        pVertexArray->appendPos(m_VertexCoords[i],m_TexCoords[i], color);
    }

    for (unsigned int i = 0; i < m_Triangles.size(); i++) {
        pVertexArray->appendTriIndexes(m_Triangles[i].x, m_Triangles[i].y, m_Triangles[i].z);
    }
}

}
<commit_msg>Mesh node fixes.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "MeshNode.h"

#include "../wrapper/WrapHelper.h"
#include "../base/Logger.h"
#include "../base/Exception.h"

#include "NodeDefinition.h"
#include "VectorNode.h"
#include "Player.h"

#include <cstdlib>
#include <string>
#include <iostream>

using namespace std;
using namespace boost::python;

namespace avg {

NodeDefinition MeshNode::createDefinition()
{
    vector<DPoint> vVert;
    vector<DPoint> vTex;
    vector<IntTriple> vTriangle;

    return NodeDefinition("mesh", (NodeBuilder)MeshNode::buildNode<MeshNode>)
        .extendDefinition(VectorNode::createDefinition())
        .addArg(Arg<vector<DPoint> >("vertexcoords", vVert, false, offsetof(MeshNode, m_VertexCoords)))
        .addArg(Arg<vector<DPoint> >("texcoords", vTex, false, offsetof(MeshNode, m_TexCoords)))
        .addArg(Arg<vector<IntTriple> >("triangles", vTriangle, false, offsetof(MeshNode, m_Triangles)))
        ;
}

MeshNode::MeshNode(const ArgList& Args)
    : VectorNode(Args)
{
    Args.setMembers(this);
    isValid(m_TexCoords);
}

MeshNode::~MeshNode()
{
}

void MeshNode::isValid(const vector<DPoint>& coords)
{
    if (coords.size() != m_VertexCoords.size()) {
        throw(Exception(AVG_ERR_OUT_OF_RANGE,
                "Coordinates Out of Range"));
    }
}

const vector<DPoint>& MeshNode::getVertexCoords() const
{
    return m_VertexCoords;
}

void MeshNode::setVertexCoords(const vector<DPoint>& coords)
{
    isValid(coords);
    m_VertexCoords = coords;
    setDrawNeeded(true);
}

const vector<DPoint>& MeshNode::getTexCoords() const
{
    return m_TexCoords;
}

void MeshNode::setTexCoords(const vector<DPoint>& coords)
{
    isValid(coords);
    m_TexCoords = coords;
    setDrawNeeded(true);
}

const vector<IntTriple>& MeshNode::getTriangles() const
{
    return m_Triangles;
}

void MeshNode::setTriangles(const vector<IntTriple>& triangles)
{
    for (unsigned int i = 0; i < triangles.size(); i++) {

        if( static_cast<unsigned int>(triangles[i].x) < 0 ||
            static_cast<unsigned int>(triangles[i].y) < 0 ||
            static_cast<unsigned int>(triangles[i].z) < 0){
            throw(Exception(AVG_ERR_OUT_OF_RANGE,
                "Triangle Index Out of Range < 0"));
        }

        if( static_cast<unsigned int>(triangles[i].x) > m_VertexCoords.size() ||
            static_cast<unsigned int>(triangles[i].y) > m_VertexCoords.size() ||
            static_cast<unsigned int>(triangles[i].z) > m_VertexCoords.size()){
            throw(Exception(AVG_ERR_OUT_OF_RANGE,
                "Triangle Index Out of Range > max triangles"));
        }
    }
    m_Triangles = triangles;
    setDrawNeeded(true);
}

int MeshNode::getNumVertexes()
{
    return m_VertexCoords.size();
}

int MeshNode::getNumIndexes()
{
    int numTriangles = m_Triangles.size()*3;
    return numTriangles;
}

void MeshNode::calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
{
    for (unsigned int i = 0; i < m_VertexCoords.size(); i++) {
        pVertexArray->appendPos(m_VertexCoords[i],m_TexCoords[i], color);
    }

    for (unsigned int i = 0; i < m_Triangles.size(); i++) {
        pVertexArray->appendTriIndexes(m_Triangles[i].x, m_Triangles[i].y, m_Triangles[i].z);
    }
}

}
<|endoftext|>


<commit_before>#include "glob.hpp"

#ifdef _WIN32   //windows環境の場合は「_WIN32」が定義されているので、こちら。

    #include <winsock2.h> // for "struct timeval" // マクロが再定義されました。主な原因は、<WinSock2.h>より先に<windows.h>がインクルードされたことです。Windowsの制約として、windows.hよりも先にwinsock2.hをインクルードすることが必要です。http://www.02.246.ne.jp/~torutk/cxx/socket/win32_socket.html
    #include <windows.h>
    #undef min
    #undef max
#else

    #include <dirent.h>
    #include <sys/stat.h>    //stat(), S_ISDIR
    #include <string.h>        //strcmp()

    #include <stdio.h>        //std::sort
    #include <vector>        //std::sort
    #include <algorithm>    //std::sort
    #include <functional>    //std::sort
#endif

#include <stdexcept>
#include <stdio.h>

#include "path.hpp"
#include "../pdbg.hpp"
#include "../string/strmatch.hpp"
#include "../typeDef.h"

//-----------------------------------------------------------------------------------------------------------------------------------------------

std::vector<std::string> _glob_worker(const std::string& search_path_in, const char* wild_card, const bool opt_d, const bool opt_f, const bool opt_r){
    DIR *pDir;
    struct dirent *pEnt;
    struct stat Stat;
    std::vector<std::string> v_path;
    std::vector<std::string> v_path_stack; // Useing STACK in order NOT to exceed the limit of opendir() number.

    v_path_stack.push_back(search_path_in);

    for(;v_path_stack.size()!=0;){
        std::string search_path = v_path_stack.back(); v_path_stack.pop_back();

        pDir = opendir(search_path.c_str());
        if(pDir==NULL){ continue; } // No files or directories.

        for(pEnt=readdir(pDir); pEnt!=0; pEnt=readdir(pDir)){
            // get file status
            std::string path = search_path + pEnt->d_name;
            if( stat( path.c_str(), &Stat ) ){
                sstd::pdbg("ERROR: glob_worker(): Failed to get stat %s\n", path.c_str());
                break;
            }
            if(!sstd::strmatch(path, wild_card)){ continue; }

            if (S_ISDIR(Stat.st_mode)){
                // when a directory
                if((strcmp( pEnt->d_name, "." )!=0) && (strcmp( pEnt->d_name, ".." )!=0)){
                    // subdirectory
                    // printf( "subdirectory: %s\n", pEnt->d_name );
                    if(opt_d){
                        v_path.push_back( path );
                    }
                    if(opt_r){
                        v_path_stack.push_back( path + '/' );
                    }
                }else{
                    //  . current directory
                    // .. parent directory
                    // printf( "current or parent directory: %s\n", pEnt->d_name );

                    // --- nothing to do ---
                }
            }else{
                // when a file
                if(opt_f){
                    v_path.push_back( path );
                }
            }
        }
        closedir(pDir);
        if(!opt_r){ break; }
    }

    return v_path;
}
std::vector<std::string> _glob_base(const char* path_wc, const bool opt_d, const bool opt_f, const bool opt_r){
    std::string search_path = sstd::getPath(path_wc);
    std::vector<std::string> v_path = _glob_worker(search_path.c_str(), path_wc, opt_d, opt_f, opt_r);
    std::sort(v_path.begin(), v_path.end());
    return v_path;
}
std::vector<std::string> sstd::glob(const char* path, const char* opt){
    bool opt_d=false;
    bool opt_f=false;
    bool opt_r=false;
    for(uint i=0; opt[i]!='\0'; ++i){
        switch(opt[i]){
        case 'd': { opt_d=true; break; }
        case 'f': { opt_f=true; break; }
        case 'r': { opt_r=true; break; }
        default: { sstd::pdbg("ERROR: glob(): Unexpected option.\n"); break; }
        }
    }
    return _glob_base(path, opt_d, opt_f, opt_r);
}
std::vector<std::string> sstd::glob(const std::string& path, const char* opt){ return sstd::glob(path.c_str(), opt); }
std::vector<std::string> sstd::glob(const        char* path){ return sstd::glob(path, "f"); }
std::vector<std::string> sstd::glob(const std::string& path){ return sstd::glob(path.c_str(), "f"); }

//-----------------------------------------------------------------------------------------------------------------------------------------------
/*

// old implimentation

std::vector<std::string> sstd::glob_f(const char* path){
#ifdef _WIN32    //windows環境の場合は「_WIN32」が定義されているので、こちら。

    HANDLE hFind;
    WIN32_FIND_DATA fd;
    std::vector<std::string> FileList;

    hFind = FindFirstFileEx(path, FindExInfoStandard, &fd, FindExSearchNameMatch, NULL, 0);
    if(hFind==INVALID_HANDLE_VALUE){ return FileList; } // No files or directories.

    do{
        if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){ // WIN32_FIND_DATA構造体のdwFileAttributesとFILE_ATTRIBUTE_DIRECTORYのビットの論理積を取り、ファイルかディレクトリかを判断している

            // directory found
            if((strcmp( fd.cFileName, "." )!=0) && (strcmp( fd.cFileName, ".." )!=0)){
                // subdirectory (サブディレクトリ)
//                printf( "subdirectory: %s\n", fd.cFileName );
            }else{
                //  . current directory (カレントディレクトリ)
                // .. parent directory (親ディレクトリ)
//                printf( "current or parent directory: %s\n", fd.cFileName );
            }
        }else{

            // file found
            std::string buf = sstd::getPath(path) + std::string( fd.cFileName );
            FileList.push_back(buf.c_str());
//            FileList.push_back(fd.cFileName);
//            printf("file: %s\n", FileList.back().c_str());
        }
    }while(FindNextFile(hFind, &fd));

    FindClose(hFind);

    return FileList;

#else            //Linux環境の場合は、「_WIN32」が定義されていないので、こちら。

    DIR *pDir;
    struct dirent *pEnt;
    struct stat Stat;
    std::string PathName;
    std::vector<std::string> FileList;

    std::string DirPath = sstd::getPath(path);

    // ディレクトリを開く
    pDir = opendir(DirPath.c_str());
    if(pDir==NULL){ return FileList; } // No files or directories.

    for(pEnt=readdir(pDir); pEnt!=0; pEnt=readdir(pDir)){

        // ファイルの情報を取得
        PathName = DirPath + pEnt->d_name;
        if( stat( PathName.c_str(), &Stat ) ){
            printf( "ERROR: Failed to get stat %s\n", PathName.c_str() );
            break;
        }

        if (S_ISDIR(Stat.st_mode)){

            // directory found
            if((strcmp( pEnt->d_name, "." )!=0) && (strcmp( pEnt->d_name, ".." )!=0)){
                // subdirectory (サブディレクトリ)
//                   printf( "subdirectory: %s\n", pEnt->d_name );
            }else{
                //  . current directory (カレントディレクトリ)
                // .. parent directory (親ディレクトリ)
//                   printf( "current or parent directory: %s\n", pEnt->d_name );
            }
        }else{
            if(sstd::strmatch( pEnt->d_name, sstd::getFileName(path))){
                // マッチした場合に true を返します。
                FileList.push_back( PathName );
            }
        }
    }

    // ハンドルを閉じる
    closedir(pDir);

    std::sort(FileList.begin(), FileList.end());//昇順ソート
    return FileList;
#endif
}
std::vector<std::string> sstd::glob_f(const std::string& path){
    return sstd::glob_f(path.c_str());
}

*/
//-----------------------------------------------------------------------------------------------------------------------------------------------
<commit_msg>rm unused lines for Windwos at sstd::glob<commit_after>#include "glob.hpp"

#include <dirent.h>
#include <sys/stat.h> //stat(), S_ISDIR
#include <string.h>   //strcmp()

#include <stdio.h>    //std::sort
#include <vector>     //std::sort
#include <algorithm>  //std::sort
#include <functional> //std::sort

#include <stdexcept>
#include <stdio.h>

#include "path.hpp"
#include "../pdbg.hpp"
#include "../string/strmatch.hpp"
#include "../typeDef.h"

//-----------------------------------------------------------------------------------------------------------------------------------------------

std::vector<std::string> _glob_worker(const std::string& search_path_in, const char* wild_card, const bool opt_d, const bool opt_f, const bool opt_r){
    DIR *pDir;
    struct dirent *pEnt;
    struct stat Stat;
    std::vector<std::string> v_path;
    std::vector<std::string> v_path_stack; // Useing STACK in order NOT to exceed the limit of opendir() number.

    v_path_stack.push_back(search_path_in);

    for(;v_path_stack.size()!=0;){
        std::string search_path = v_path_stack.back(); v_path_stack.pop_back();

        pDir = opendir(search_path.c_str());
        if(pDir==NULL){ continue; } // No files or directories.

        for(pEnt=readdir(pDir); pEnt!=0; pEnt=readdir(pDir)){
            // get file status
            std::string path = search_path + pEnt->d_name;
            if( stat( path.c_str(), &Stat ) ){
                sstd::pdbg("ERROR: glob_worker(): Failed to get stat %s\n", path.c_str());
                break;
            }
            if(!sstd::strmatch(path, wild_card)){ continue; }

            if (S_ISDIR(Stat.st_mode)){
                // when a directory
                if((strcmp( pEnt->d_name, "." )!=0) && (strcmp( pEnt->d_name, ".." )!=0)){
                    // subdirectory
                    // printf( "subdirectory: %s\n", pEnt->d_name );
                    if(opt_d){
                        v_path.push_back( path );
                    }
                    if(opt_r){
                        v_path_stack.push_back( path + '/' );
                    }
                }else{
                    //  . current directory
                    // .. parent directory
                    // printf( "current or parent directory: %s\n", pEnt->d_name );

                    // --- nothing to do ---
                }
            }else{
                // when a file
                if(opt_f){
                    v_path.push_back( path );
                }
            }
        }
        closedir(pDir);
        if(!opt_r){ break; }
    }

    return v_path;
}
std::vector<std::string> _glob_base(const char* path_wc, const bool opt_d, const bool opt_f, const bool opt_r){
    std::string search_path = sstd::getPath(path_wc);
    std::vector<std::string> v_path = _glob_worker(search_path.c_str(), path_wc, opt_d, opt_f, opt_r);
    std::sort(v_path.begin(), v_path.end());
    return v_path;
}
std::vector<std::string> sstd::glob(const char* path, const char* opt){
    bool opt_d=false;
    bool opt_f=false;
    bool opt_r=false;
    for(uint i=0; opt[i]!='\0'; ++i){
        switch(opt[i]){
        case 'd': { opt_d=true; break; }
        case 'f': { opt_f=true; break; }
        case 'r': { opt_r=true; break; }
        default: { sstd::pdbg("ERROR: glob(): Unexpected option.\n"); break; }
        }
    }
    return _glob_base(path, opt_d, opt_f, opt_r);
}
std::vector<std::string> sstd::glob(const std::string& path, const char* opt){ return sstd::glob(path.c_str(), opt); }
std::vector<std::string> sstd::glob(const        char* path){ return sstd::glob(path, "f"); }
std::vector<std::string> sstd::glob(const std::string& path){ return sstd::glob(path.c_str(), "f"); }

//-----------------------------------------------------------------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------------------------------------------------------------
<|endoftext|>