summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2014-03-10 20:24:23 +0000
committerrandomdan <randomdan@localhost>2014-03-10 20:24:23 +0000
commit349993be0149356ac783349a9f1d4012b44a4dbb (patch)
tree114a2d8c8b1534f05fe10d002ff031f590e4f3f8
parentAdds native support for time_duration as a variable type (diff)
downloadproject2-349993be0149356ac783349a9f1d4012b44a4dbb.tar.bz2
project2-349993be0149356ac783349a9f1d4012b44a4dbb.tar.xz
project2-349993be0149356ac783349a9f1d4012b44a4dbb.zip
Add basic workings of the Ice client and daemon modules - will probably change, but basic functionality works
-rw-r--r--project2/Jamfile.jam2
-rw-r--r--project2/basics/preload.cpp2
-rw-r--r--project2/common/commonObjects.cpp1
-rw-r--r--project2/common/flatView.cpp58
-rw-r--r--project2/common/flatView.h28
-rw-r--r--project2/ice/Jamfile.jam69
-rw-r--r--project2/ice/buildClient.cpp33
-rw-r--r--project2/ice/buildClient.h19
-rw-r--r--project2/ice/buildComms.cpp32
-rw-r--r--project2/ice/buildComms.h17
-rw-r--r--project2/ice/buildDaemon.cpp36
-rw-r--r--project2/ice/buildDaemon.h19
-rw-r--r--project2/ice/buildShared.cpp30
-rw-r--r--project2/ice/buildShared.h20
-rw-r--r--project2/ice/iceClient.cpp8
-rw-r--r--project2/ice/iceClient.h38
-rw-r--r--project2/ice/iceCompile.cpp115
-rw-r--r--project2/ice/iceCompile.h51
-rw-r--r--project2/ice/iceConvert.cpp74
-rw-r--r--project2/ice/iceConvert.h47
-rw-r--r--project2/ice/iceDaemon.cpp161
-rw-r--r--project2/ice/iceDaemon.h30
-rw-r--r--project2/ice/iceDataSource.cpp43
-rw-r--r--project2/ice/iceDataSource.h43
-rw-r--r--project2/ice/iceModule.cpp22
-rw-r--r--project2/ice/iceModule.h70
-rw-r--r--project2/ice/iceRows.h87
-rw-r--r--project2/ice/iceTask.h22
-rw-r--r--project2/ice/pch.hpp21
-rw-r--r--project2/ice/slice2Daemon.cpp86
-rw-r--r--project2/ice/slice2Daemon.h24
-rw-r--r--project2/ice/slice2DaemonLoader.cpp46
-rw-r--r--project2/ice/slice2DaemonLoader.h21
-rw-r--r--project2/ice/slice2Presenter.cpp60
-rw-r--r--project2/ice/slice2Presenter.h23
-rw-r--r--project2/ice/slice2Rows.cpp94
-rw-r--r--project2/ice/slice2Rows.h24
-rw-r--r--project2/ice/slice2Task.cpp86
-rw-r--r--project2/ice/slice2Task.h24
-rw-r--r--project2/ice/slice2Type.cpp110
-rw-r--r--project2/ice/slice2Type.h25
-rw-r--r--project2/ice/sliceCompile.cpp59
-rw-r--r--project2/ice/sliceCompile.h21
43 files changed, 1900 insertions, 1 deletions
diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam
index c432bfa..2aca8d7 100644
--- a/project2/Jamfile.jam
+++ b/project2/Jamfile.jam
@@ -13,6 +13,7 @@ alias p2parts : : : :
<library>mail//p2mail
<library>regex//p2regex
<library>xml//p2xml
+ <library>ice//p2iceclient
<library>json//p2json
<library>compression//p2compression
<library>streams//p2streams
@@ -21,6 +22,7 @@ alias p2parts : : : :
;
alias p2daemonparts : : : :
+ <library>ice//p2icedaemon
;
build-project console ;
diff --git a/project2/basics/preload.cpp b/project2/basics/preload.cpp
index 104dc22..03f275b 100644
--- a/project2/basics/preload.cpp
+++ b/project2/basics/preload.cpp
@@ -19,7 +19,7 @@ class Preload {
{
const auto beforeOpts = InstanceSet<Options>::GetAll();
- void * handle = dlopen(librarypath, RTLD_NOW);
+ void * handle = dlopen(librarypath, RTLD_GLOBAL | RTLD_NOW);
if (handle) {
Logger()->messagebf(LOG_DEBUG, "Loaded library '%s'", librarypath.as<std::string>());
}
diff --git a/project2/common/commonObjects.cpp b/project2/common/commonObjects.cpp
index a25bb9f..cb973cc 100644
--- a/project2/common/commonObjects.cpp
+++ b/project2/common/commonObjects.cpp
@@ -1,5 +1,6 @@
#include <pch.hpp>
#include "commonObjects.h"
+#include "logger.h"
#include "safeMapFind.h"
#include "scriptLoader.h"
diff --git a/project2/common/flatView.cpp b/project2/common/flatView.cpp
new file mode 100644
index 0000000..05e8b09
--- /dev/null
+++ b/project2/common/flatView.cpp
@@ -0,0 +1,58 @@
+#include "pch.hpp"
+#include "flatView.h"
+#include "presenter.h"
+#include "scopeObject.h"
+#include "scriptLoader.h"
+#include "scopeObject.h"
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+
+DECLARE_LOADER("flatview", FlatView);
+
+FlatView::FlatView(ScriptNodePtr p) :
+ SourceObject(p),
+ RowProcessor(p),
+ recordName(p, "recordname"),
+ required(p, "required", false)
+{
+ BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("columns")) {
+ viewColumns.insert(Columns::value_type(node->get_name(), Variable(node)));
+ }
+}
+
+FlatView::~FlatView()
+{
+}
+
+void
+FlatView::loadComplete(const CommonObjects * co)
+{
+ RowProcessor::loadComplete(co);
+}
+
+void
+FlatView::rowReady(const RowState * rs, const RowSetPresenter * presenter, ExecContext * ec, bool & rowsFound) const
+{
+ rowsFound = true;
+ presenter->addNewRow(recordName(ec));
+ if (viewColumns.empty()) {
+ rs->foreachColumn(ec, boost::bind(&RowSetPresenter::addNamedValue, presenter, _2, _3));
+ }
+ else {
+ BOOST_FOREACH(const Columns::value_type & col, viewColumns) {
+ presenter->addNamedValue(col.first, col.second(ec));
+ }
+ }
+ presenter->finishRow();
+}
+
+void
+FlatView::execute(const RowSetPresenter * p, ExecContext * ec) const
+{
+ bool rowsFound = false;
+ RowProcessor::execute(ec, boost::bind(&FlatView::rowReady, this, _1, p, ec, boost::ref(rowsFound)));
+ if (required(ec) && !rowsFound) {
+ throw EmptyRequiredRows(name);
+ }
+}
+
diff --git a/project2/common/flatView.h b/project2/common/flatView.h
new file mode 100644
index 0000000..5dc24dc
--- /dev/null
+++ b/project2/common/flatView.h
@@ -0,0 +1,28 @@
+#ifndef FLATVIEW_H
+#define FLATVIEW_H
+
+#include <boost/intrusive_ptr.hpp>
+#include "rowProcessor.h"
+#include "view.h"
+#include "aggregate.h"
+
+/// Project2 component to create output based on a records in a flat row set
+class FlatView : public SourceObject, public RowProcessor {
+ public:
+ FlatView(ScriptNodePtr);
+ virtual ~FlatView();
+
+ void loadComplete(const CommonObjects *);
+ void execute(const RowSetPresenter *, ExecContext *) const;
+ void rowReady(const RowState *, const RowSetPresenter *, ExecContext *, bool & found) const;
+
+ const Variable recordName;
+ const Variable required;
+
+ protected:
+ typedef std::map<Glib::ustring, Variable> Columns;
+ Columns viewColumns;
+};
+
+#endif
+
diff --git a/project2/ice/Jamfile.jam b/project2/ice/Jamfile.jam
new file mode 100644
index 0000000..4ecca91
--- /dev/null
+++ b/project2/ice/Jamfile.jam
@@ -0,0 +1,69 @@
+alias glibmm : : : :
+ <cflags>"`pkg-config --cflags glibmm-2.4`"
+ <linkflags>"`pkg-config --libs glibmm-2.4`"
+ ;
+
+lib dl ;
+lib Slice ;
+lib Ice ;
+lib IceUtil ;
+lib pthread ;
+lib boost_filesystem ;
+
+cpp-pch pch : pch.hpp :
+ <include>../../libmisc
+ <library>../lib//p2lib
+ <library>../common//p2common
+ <library>glibmm
+ ;
+
+lib p2iceclient :
+ pch iceDataSource.cpp iceClient.cpp buildClient.cpp slice2Task.cpp slice2Rows.cpp
+ :
+ <include>../../libmisc
+ <library>glibmm
+ <library>../common//p2common
+ <library>../lib//p2lib
+ <library>p2ice
+ <library>dl
+ <library>Ice
+ <library>Slice
+ <library>IceUtil
+ <library>boost_filesystem
+ <library>pthread
+ : :
+ <library>p2ice
+ ;
+
+lib p2icedaemon :
+ pch iceDaemon.cpp iceModule.cpp buildDaemon.cpp slice2Daemon.cpp slice2DaemonLoader.cpp slice2Presenter.cpp
+ :
+ <include>../../libmisc
+ <library>glibmm
+ <library>../common//p2common
+ <library>../lib//p2lib
+ <library>../daemon/lib//p2daemonlib
+ <library>p2ice
+ <library>dl
+ <library>Ice
+ <library>Slice
+ <library>IceUtil
+ <library>boost_filesystem
+ : :
+ <library>../daemon/lib//p2daemonlib
+ <library>p2ice
+ ;
+
+lib p2ice :
+ pch iceConvert.cpp iceCompile.cpp sliceCompile.cpp buildComms.cpp buildShared.cpp slice2Type.cpp
+ :
+ <include>../../libmisc
+ <library>glibmm
+ <library>../common//p2common
+ <library>../lib//p2lib
+ <library>dl
+ <library>Ice
+ <library>Slice
+ <library>IceUtil
+ <library>boost_filesystem
+ ;
diff --git a/project2/ice/buildClient.cpp b/project2/ice/buildClient.cpp
new file mode 100644
index 0000000..676af31
--- /dev/null
+++ b/project2/ice/buildClient.cpp
@@ -0,0 +1,33 @@
+#include <pch.hpp>
+#include "buildClient.h"
+#include "slice2Task.h"
+#include "slice2Rows.h"
+
+BuildClient::BuildClient(const boost::filesystem::path & slice, const IceCompile::Deps & dep) :
+ SliceCompile(slice, dep)
+{
+}
+
+void
+BuildClient::Headers(FILE * out) const
+{
+ fprintf(out, "#include <iceTask.h>\n");
+ fprintf(out, "#include <iceRows.h>\n");
+}
+
+void
+BuildClient::Body(FILE * out, Slice::UnitPtr u) const
+{
+ Slice2Task taskBuilder(out);
+ Slice2Rows rowsBuilder(out);
+ u->visit(&taskBuilder, false);
+ u->visit(&rowsBuilder, false);
+}
+
+boost::filesystem::path
+BuildClient::OutputName(const std::string & type) const
+{
+ return slice.filename().replace_extension(".client" + type);
+}
+
+
diff --git a/project2/ice/buildClient.h b/project2/ice/buildClient.h
new file mode 100644
index 0000000..a8c0b6c
--- /dev/null
+++ b/project2/ice/buildClient.h
@@ -0,0 +1,19 @@
+#ifndef BUILDCLIENT_H
+#define BUILDCLIENT_H
+
+#include "sliceCompile.h"
+#include <string>
+
+class BuildClient : public SliceCompile {
+ public:
+ BuildClient(const boost::filesystem::path & slice, const IceCompile::Deps & dep);
+
+ virtual void Headers(FILE *) const;
+ virtual void Body(FILE *, Slice::UnitPtr) const;
+
+ boost::filesystem::path OutputName(const std::string & type) const;
+};
+
+#endif
+
+
diff --git a/project2/ice/buildComms.cpp b/project2/ice/buildComms.cpp
new file mode 100644
index 0000000..4add6c7
--- /dev/null
+++ b/project2/ice/buildComms.cpp
@@ -0,0 +1,32 @@
+#include <pch.hpp>
+#include "buildComms.h"
+#include <logger.h>
+#include <misc.h>
+
+BuildComms::BuildComms(const boost::filesystem::path & slice) :
+ IceCompile(slice)
+{
+}
+
+void
+BuildComms::Build(const boost::filesystem::path & in, const boost::filesystem::path & out) const
+{
+ const auto slicecmd = stringbf("%s --output-dir %s %s", slice2cpp, out.parent_path(), in);
+ Logger()->messagebf(LOG_DEBUG, "%s: slice command: %s", __PRETTY_FUNCTION__, slicecmd);
+ if (system(slicecmd.c_str())) {
+ throw std::runtime_error("slice2cpp failed");
+ }
+}
+
+boost::filesystem::path
+BuildComms::InputPath() const
+{
+ return slice;
+}
+
+boost::filesystem::path
+BuildComms::OutputName(const std::string & type) const
+{
+ return slice.filename().replace_extension(type);
+}
+
diff --git a/project2/ice/buildComms.h b/project2/ice/buildComms.h
new file mode 100644
index 0000000..31e7590
--- /dev/null
+++ b/project2/ice/buildComms.h
@@ -0,0 +1,17 @@
+#ifndef BUILDCOMMS_H
+#define BUILDCOMMS_H
+
+#include "iceCompile.h"
+#include <string>
+
+class BuildComms : public IceCompile {
+ public:
+ BuildComms(const boost::filesystem::path & slice);
+
+ void Build(const boost::filesystem::path & in, const boost::filesystem::path & out) const;
+ boost::filesystem::path InputPath() const;
+ boost::filesystem::path OutputName(const std::string & type) const;
+};
+
+#endif
+
diff --git a/project2/ice/buildDaemon.cpp b/project2/ice/buildDaemon.cpp
new file mode 100644
index 0000000..83976b0
--- /dev/null
+++ b/project2/ice/buildDaemon.cpp
@@ -0,0 +1,36 @@
+#include <pch.hpp>
+#include "buildDaemon.h"
+#include "slice2Presenter.h"
+#include "slice2Daemon.h"
+#include "slice2DaemonLoader.h"
+
+BuildDaemon::BuildDaemon(const boost::filesystem::path & slice, const IceCompile::Deps & dep) :
+ SliceCompile(slice, dep)
+{
+}
+
+void
+BuildDaemon::Headers(FILE * out) const
+{
+ fprintf(out, "#include <iceModule.h>\n");
+}
+
+void
+BuildDaemon::Body(FILE * out, Slice::UnitPtr u) const
+{
+ Slice2Presenter presenterBuilder(out);
+ u->visit(&presenterBuilder, false);
+
+ Slice2Daemon daemonBuilder(out);
+ u->visit(&daemonBuilder, false);
+
+ Slice2DaemonLoader daemonLoaderBuilder(out);
+ u->visit(&daemonLoaderBuilder, false);
+}
+
+boost::filesystem::path
+BuildDaemon::OutputName(const std::string & type) const
+{
+ return slice.filename().replace_extension(".daemon" + type);
+}
+
diff --git a/project2/ice/buildDaemon.h b/project2/ice/buildDaemon.h
new file mode 100644
index 0000000..8c22ea6
--- /dev/null
+++ b/project2/ice/buildDaemon.h
@@ -0,0 +1,19 @@
+#ifndef BUILDDAEMON_H
+#define BUILDDAEMON_H
+
+#include "sliceCompile.h"
+#include <string>
+
+class BuildDaemon : public SliceCompile {
+ public:
+ BuildDaemon(const boost::filesystem::path & slice, const IceCompile::Deps & dep);
+
+ virtual void Headers(FILE *) const;
+ virtual void Body(FILE *, Slice::UnitPtr) const;
+
+ boost::filesystem::path OutputName(const std::string & type) const;
+};
+
+#endif
+
+
diff --git a/project2/ice/buildShared.cpp b/project2/ice/buildShared.cpp
new file mode 100644
index 0000000..61450c8
--- /dev/null
+++ b/project2/ice/buildShared.cpp
@@ -0,0 +1,30 @@
+#include <pch.hpp>
+#include "buildShared.h"
+#include "slice2Type.h"
+
+BuildShared::BuildShared(const boost::filesystem::path & slice, const IceCompile::Deps & dep) :
+ SliceCompile(slice, dep)
+{
+}
+
+void
+BuildShared::Headers(FILE * out) const
+{
+ fprintf(out, "#include <iceConvert.h>\n");
+}
+
+void
+BuildShared::Body(FILE * out, Slice::UnitPtr u) const
+{
+ Slice2Type typeBuilder(out);
+ u->visit(&typeBuilder, false);
+}
+
+boost::filesystem::path
+BuildShared::OutputName(const std::string & type) const
+{
+ return slice.filename().replace_extension(".shared" + type);
+}
+
+
+
diff --git a/project2/ice/buildShared.h b/project2/ice/buildShared.h
new file mode 100644
index 0000000..cf0e5d5
--- /dev/null
+++ b/project2/ice/buildShared.h
@@ -0,0 +1,20 @@
+#ifndef BUILDSHARED_H
+#define BUILDSHARED_H
+
+#include "sliceCompile.h"
+#include <string>
+
+class BuildShared : public SliceCompile {
+ public:
+ BuildShared(const boost::filesystem::path & slice, const IceCompile::Deps & dep);
+
+ virtual void Headers(FILE *) const;
+ virtual void Body(FILE *, Slice::UnitPtr) const;
+
+ boost::filesystem::path OutputName(const std::string & type) const;
+};
+
+#endif
+
+
+
diff --git a/project2/ice/iceClient.cpp b/project2/ice/iceClient.cpp
new file mode 100644
index 0000000..3045241
--- /dev/null
+++ b/project2/ice/iceClient.cpp
@@ -0,0 +1,8 @@
+#include <pch.hpp>
+#include "iceClient.h"
+
+IceClientBase::IceClientBase(ScriptNodePtr p) :
+ dataSource(p, "datasource"),
+ objectId(p, "objectId")
+{
+}
diff --git a/project2/ice/iceClient.h b/project2/ice/iceClient.h
new file mode 100644
index 0000000..93042fd
--- /dev/null
+++ b/project2/ice/iceClient.h
@@ -0,0 +1,38 @@
+#ifndef ICECLIENT_H
+#define ICECLIENT_H
+
+#include <variables.h>
+#include <commonObjects.h>
+#include <Ice/Ice.h>
+#include "iceDataSource.h"
+
+class IceClientBase {
+ public:
+ IceClientBase(ScriptNodePtr p);
+
+ protected:
+ const Variable dataSource;
+ const Variable objectId;
+ const IceDataSource * ice;
+};
+
+template <typename Interface>
+class IceClient : public IceClientBase {
+ public:
+ IceClient(ScriptNodePtr p) : IceClientBase(p) { }
+
+ void loadComplete(const CommonObjects * co)
+ {
+ ice = co->dataSource<IceDataSource>(dataSource(NULL));
+ service = ice->GetProxy<Interface>(objectId(NULL), NULL);
+ if (!service) {
+ throw std::runtime_error("Invalid service proxy");
+ }
+ }
+
+ protected:
+ Interface service;
+};
+
+#endif
+
diff --git a/project2/ice/iceCompile.cpp b/project2/ice/iceCompile.cpp
new file mode 100644
index 0000000..d9287f4
--- /dev/null
+++ b/project2/ice/iceCompile.cpp
@@ -0,0 +1,115 @@
+#include <pch.hpp>
+#include "iceCompile.h"
+#include <boost/filesystem/operations.hpp>
+#include <logger.h>
+#include <misc.h>
+#include <dlfcn.h>
+
+namespace fs = boost::filesystem;
+
+std::string IceCompile::slice2cpp;
+std::string IceCompile::cxx;
+std::string IceCompile::linker;
+std::string IceCompile::cxxopts;
+std::string IceCompile::linkeropts;
+fs::path IceCompile::tmpdir;
+fs::path IceCompile::headerdir;
+
+DECLARE_OPTIONS(IceCompile, "ICE Compile Options")
+("ice.compile.cxx", Options::value(&cxx, "g++"),
+ "The C++ compiler to use")
+("ice.compile.cxxopts", Options::value(&cxxopts, "-Wall -Werror -std=c++11 -O3 -march=native -fPIC"),
+ "The extra arguments to pass to the C++ compiler")
+("ice.compile.linker", Options::value(&linker, "g++"),
+ "The linker to use")
+("ice.compile.linkeropts", Options::value(&linkeropts, ""),
+ "The extra arguments to pass to linker")
+("ice.compile.slice2cpp", Options::value(&slice2cpp, "slice2cpp"),
+ "The ICE Slice to CPP processor to use")
+("ice.compile.tmpdir", Options::value(&tmpdir, "/tmp/project2.slice"),
+ "The temporary directory used when compiling")
+("ice.compile.headers", Options::value(&headerdir, "/usr/include/project2"),
+ "The root folder where Project2 header files are found")
+END_OPTIONS(IceCompile);
+
+IceCompile::IceCompile(const boost::filesystem::path & s) :
+ slice(s)
+{
+}
+
+IceCompile::IceCompile(const boost::filesystem::path & s, const Deps & d) :
+ slice(s),
+ deps(d)
+{
+}
+
+void
+IceCompile::Update() const
+{
+ fs::create_directories(IceCompile::tmpdir);
+ BOOST_FOREACH(const auto & dep, deps) {
+ dep->Update();
+ }
+ const fs::path cpp(tmpdir / OutputName(".cpp"));
+ update(InputPath(), cpp, &IceCompile::Build);
+ const fs::path o(tmpdir / OutputName(".o"));
+ update(cpp, o, &IceCompile::Compile);
+ const fs::path so(tmpdir / OutputName(".so"));
+ update(o, so, &IceCompile::Link);
+}
+
+void
+IceCompile::update(const fs::path & in, const fs::path & out, UpdateFunc func) const
+{
+ if (!fs::exists(out) || std::max(fs::last_write_time(in), fs::last_write_time("/proc/self/exe")) > fs::last_write_time(out)) {
+ Logger()->messagebf(LOG_DEBUG, "updating %s from %s", out, in);
+ (this->*func)(in, out);
+ }
+ else {
+ Logger()->messagebf(LOG_DEBUG, "%s already up to date", out);
+ }
+}
+
+void
+IceCompile::Compile(const fs::path & in, const fs::path & out) const
+{
+ const auto compile = stringbf(
+ "%s %s -o %s -x c++ -c -I %s -I %s -I ../libmisc/ -I %s -I %s -I %s `pkg-config --cflags glibmm-2.4` %s",
+ cxx, cxxopts, out, tmpdir,
+ headerdir / "lib",
+ headerdir / "common",
+ headerdir / "ice",
+ headerdir / "daemon" / "lib",
+ in);
+ Logger()->messagebf(LOG_DEBUG, "compile command: %s", compile);
+ if (system(compile.c_str())) {
+ throw std::runtime_error("compile failed");
+ }
+}
+
+void
+IceCompile::Link(const fs::path & in, const fs::path & out) const
+{
+ auto link = stringbf("%s %s -o %s -shared %s", linker, linkeropts, out, in);
+ BOOST_FOREACH(const auto & dep, deps) {
+ link += " " + (tmpdir / dep->OutputName(".so")).string();
+ }
+ Logger()->messagebf(LOG_DEBUG, "link command: %s", link);
+ if (system(link.c_str())) {
+ throw std::runtime_error("link failed");
+ }
+}
+
+IceCompile::LibHandle
+IceCompile::Open() const
+{
+ void * handle = dlopen((IceCompile::tmpdir / OutputName(".so")).string().c_str(), RTLD_GLOBAL | RTLD_NOW);
+ if (!handle) {
+ std::string msg(dlerror());
+ Logger()->messagebf(LOG_ERR, "Failed to load compiled module (%s)", msg);
+ throw std::runtime_error(msg);
+ }
+ return LibHandle(handle, &dlclose);
+}
+
+
diff --git a/project2/ice/iceCompile.h b/project2/ice/iceCompile.h
new file mode 100644
index 0000000..d403d9e
--- /dev/null
+++ b/project2/ice/iceCompile.h
@@ -0,0 +1,51 @@
+#ifndef ICECOMPILE_H
+#define ICECOMPILE_H
+
+#include "options.h"
+#include <string>
+#include <boost/filesystem/path.hpp>
+#include <boost/optional.hpp>
+
+class IceCompile {
+ public:
+ INITOPTIONS;
+
+ typedef std::vector<const IceCompile *> Deps;
+
+ static std::string slice2cpp;
+ static std::string cxx;
+ static std::string linker;
+ static std::string cxxopts;
+ static std::string linkeropts;
+ static boost::filesystem::path tmpdir;
+ static boost::filesystem::path headerdir;
+
+ IceCompile(const boost::filesystem::path & slice);
+ IceCompile(const boost::filesystem::path & slice, const Deps & deps);
+
+ /// Conditionally execute Build, Compile, Link as required
+ void Update() const;
+ /// Source file path (e.g. /some/path/slice.ice)
+ virtual boost::filesystem::path InputPath() const = 0;
+ /// File name (no extension) in temporary directory (e.g. clientSlice)
+ virtual boost::filesystem::path OutputName(const std::string & type) const = 0;
+
+ typedef boost::shared_ptr<void> LibHandle;
+ LibHandle Open() const;
+
+ protected:
+ virtual void Build(const boost::filesystem::path & in, const boost::filesystem::path & out) const = 0;
+ void Compile(const boost::filesystem::path & in, const boost::filesystem::path & out) const;
+ void Link(const boost::filesystem::path & in, const boost::filesystem::path & out) const;
+
+ typedef void (IceCompile::*UpdateFunc)(const boost::filesystem::path & in, const boost::filesystem::path & out) const;
+ void update(const boost::filesystem::path & in, const boost::filesystem::path & out, UpdateFunc func) const;
+
+ const boost::filesystem::path slice;
+
+ private:
+ const Deps deps;
+};
+
+#endif
+
diff --git a/project2/ice/iceConvert.cpp b/project2/ice/iceConvert.cpp
new file mode 100644
index 0000000..1169aad
--- /dev/null
+++ b/project2/ice/iceConvert.cpp
@@ -0,0 +1,74 @@
+#include <pch.hpp>
+#include "iceConvert.h"
+#include <boost/numeric/conversion/cast.hpp>
+
+template<>
+VariableType
+IceConvert< ::Ice::Short>::ToVariable(const ::Ice::Short & s)
+{
+ return VariableType(s);
+}
+
+template<>
+VariableType
+IceConvert< ::Ice::Int>::ToVariable(const ::Ice::Int & i)
+{
+ return VariableType(i);
+}
+
+template<>
+VariableType
+IceConvert< ::Ice::Long>::ToVariable(const ::Ice::Long & l)
+{
+ return VariableType(l);
+}
+
+template<>
+VariableType
+IceConvert<bool>::ToVariable(const bool & b)
+{
+ return VariableType(b);
+}
+
+template<>
+VariableType
+IceConvert< ::std::string>::ToVariable(const ::std::string & s)
+{
+ return VariableType(s);
+}
+
+template<>
+Ice::Short
+IceConvert< ::Ice::Short>::FromVariable(const VariableType & s)
+{
+ return boost::numeric_cast<Ice::Short>(s.as<int64_t>());
+}
+
+template<>
+Ice::Int
+IceConvert< ::Ice::Int>::FromVariable(const VariableType & i)
+{
+ return i;
+}
+
+template<>
+Ice::Long
+IceConvert< ::Ice::Long>::FromVariable(const VariableType & l)
+{
+ return l;
+}
+
+template<>
+bool
+IceConvert<bool>::FromVariable(const VariableType & b)
+{
+ return b;
+}
+
+template<>
+std::string
+IceConvert< ::std::string>::FromVariable(const VariableType & s)
+{
+ return s;
+}
+
diff --git a/project2/ice/iceConvert.h b/project2/ice/iceConvert.h
new file mode 100644
index 0000000..86e42d4
--- /dev/null
+++ b/project2/ice/iceConvert.h
@@ -0,0 +1,47 @@
+#ifndef ICECONVERT_H
+#define ICECONVERT_H
+
+#include <variableType.h>
+#include <boost/function.hpp>
+#include <Ice/Ice.h>
+
+template <typename IceType>
+class IceConvert {
+ public:
+ static IceType FromVariable(const VariableType &);
+ static VariableType ToVariable(const IceType &);
+};
+
+template <typename IceOptionalType>
+class IceConvert<IceUtil::Optional<IceOptionalType>> {
+ public:
+ static IceUtil::Optional<IceOptionalType> FromVariable(const VariableType & v)
+ {
+ if (!boost::get<Null>(&v)) {
+ return IceConvert<IceOptionalType>::FromVariable(v);
+ }
+ return IceUtil::Optional<IceOptionalType>();
+ }
+
+ static VariableType ToVariable(const IceUtil::Optional<IceOptionalType> & v)
+ {
+ if (v) {
+ return IceConvert<IceOptionalType>::ToVariable(*v);
+ }
+ return Null();
+ }
+};
+
+typedef boost::function<void(const std::string &)> IceEachDataMemberName;
+typedef boost::function<void(VariableType)> IceEachDataMemberValue;
+
+template <typename RowType>
+class IceType {
+ public:
+ static void CreateColumns(const IceEachDataMemberName & func);
+ static void ForEachDataMember(const IceInternal::Handle< RowType > & ptr, const IceEachDataMemberValue & func);
+ static void ForEachDataMember(const RowType & ptr, const IceEachDataMemberValue & func);
+};
+
+#endif
+
diff --git a/project2/ice/iceDaemon.cpp b/project2/ice/iceDaemon.cpp
new file mode 100644
index 0000000..01acb36
--- /dev/null
+++ b/project2/ice/iceDaemon.cpp
@@ -0,0 +1,161 @@
+#include <pch.hpp>
+#include "iceDaemon.h"
+#include "buildComms.h"
+#include "buildShared.h"
+#include "buildDaemon.h"
+#include <scriptLoader.h>
+#include <options.h>
+#include <sys/stat.h>
+#include <boost/foreach.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+#include <commonObjects.h>
+#include <logger.h>
+#include <checkHost.h>
+#include <flatView.h>
+#include <taskHost.h>
+#include <execContext.h>
+#include <misc.h>
+#include <exceptions.h>
+
+std::string IceDaemon::adapterName;
+std::string IceDaemon::adapterEndpoint;
+std::string IceDaemon::interface;
+std::string IceDaemon::slice;
+std::string IceDaemon::viewRoot;
+std::string IceDaemon::taskRoot;
+
+DECLARE_GENERIC_LOADER("ice", DaemonLoader, IceDaemon);
+DECLARE_OPTIONS(IceDaemon, "ICE Daemon Options")
+("ice.daemon.viewRoot", Options::value(&viewRoot, "views"),
+ "The folder in which to find view scripts")
+("ice.daemon.taskRoot", Options::value(&taskRoot, "tasks"),
+ "The folder in which to find task scripts")
+("ice.daemon.adapterName", Options::value(&adapterName, "DefaultAdapter"),
+ "The name of the ICE adapter created")
+("ice.daemon.adapterEndpoint", Options::value(&adapterEndpoint),
+ "The ICE endpoint string for the ICE adapter")
+("ice.daemon.slice", Options::value(&slice),
+ "The ICE Slice file to compile")
+("ice.daemon.interface", Options::value(&interface),
+ "The ICE interface to wrap")
+END_OPTIONS(IceDaemon);
+
+IceDaemon::IceDaemon(int & argc, char ** argv) :
+ ic(Ice::initialize(argc, argv))
+{
+}
+
+IceDaemon::~IceDaemon()
+{
+ ic->destroy();
+}
+
+void
+IceDaemon::shutdown() const
+{
+ ic->shutdown();
+}
+
+void
+IceDaemon::run() const
+{
+ Logger()->messagebf(LOG_INFO, ">>> %s compiling slice '%s'...", __PRETTY_FUNCTION__, slice);
+
+ BuildComms bc(slice);
+ BuildShared bds(slice, { &bc });
+ BuildDaemon bd(slice, { &bds });
+ bd.Update();
+
+ auto library = bd.Open();
+
+ Logger()->messagebf(LOG_INFO, " %s starting...", __PRETTY_FUNCTION__);
+ Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithEndpoints(adapterName, adapterEndpoint);
+ IceDaemonAdapterHandlerPtr interfacePtr = IceDaemonAdapterHandlerLoader::createNew(interface);
+ interfacePtr->add(adapter, this, ic);
+ adapter->activate();
+ Logger()->messagebf(LOG_INFO, " %s running...", __PRETTY_FUNCTION__);
+ interfacePtr->remove(adapter, ic);
+ ic->waitForShutdown();
+ Logger()->messagebf(LOG_INFO, " %s stopped...", __PRETTY_FUNCTION__);
+
+ Logger()->messagebf(LOG_INFO, "<<< %s", __PRETTY_FUNCTION__);
+}
+
+class IceDaemonFlatViewHost : public virtual CommonObjects, public virtual CheckHost {
+ public:
+ IceDaemonFlatViewHost(ScriptNodePtr s) :
+ CommonObjects(s),
+ CheckHost(s)
+ {
+ s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&view));
+ }
+ void executeView(RowSetPresenterPtr presenter, ExecContext * ec) const
+ {
+ loadScriptComponents();
+ view->execute(presenter.get(), ec);
+ // Caches might open transactions
+ BOOST_FOREACH(const CommonObjects::DataSources::value_type & ds, CommonObjects::datasources) {
+ ds.second->commit();
+ }
+ }
+ private:
+ typedef boost::intrusive_ptr<FlatView> ViewPtr;
+ ViewPtr view;
+};
+
+class IceCallContext : public ExecContext {
+ public:
+ IceCallContext(const ParamMap & p) :
+ params(p)
+ {
+ }
+
+ VariableType getParameter(const VariableType & key) const
+ {
+ return safeMapLookup<ParamNotFound>(params, key);
+ }
+
+ SessionPtr getSession() const
+ {
+ // There's no way to tell clients apart
+ throw NotSupported(__FUNCTION__);
+ }
+
+ private:
+ const ParamMap & params;
+};
+
+void
+IceDaemon::executeView(const std::string & name, RowSetPresenterPtr p, const ParamMap & pm) const
+{
+ ScriptNodePtr s = ScriptReader::resolveScript(IceDaemon::viewRoot, name, false)->root();
+ IceDaemonFlatViewHost f(s);
+ IceCallContext icc(pm);
+ f.executeView(p, &icc);
+}
+
+class IceDaemonTaskHost : public TaskHost {
+ public:
+ IceDaemonTaskHost(ScriptNodePtr s) :
+ SourceObject(s),
+ CheckHost(s),
+ TaskHost(s)
+ {
+ }
+ void executeTask(ExecContext * ec) const
+ {
+ runChecks(ec);
+ execute(ec);
+ }
+};
+
+void
+IceDaemon::executeTask(const std::string & name, const ParamMap & pm) const
+{
+ ScriptNodePtr s = ScriptReader::resolveScript(IceDaemon::taskRoot, name, false)->root();
+ IceDaemonTaskHost t(s);
+ IceCallContext icc(pm);
+ t.executeTask(&icc);
+}
+
diff --git a/project2/ice/iceDaemon.h b/project2/ice/iceDaemon.h
new file mode 100644
index 0000000..49af50b
--- /dev/null
+++ b/project2/ice/iceDaemon.h
@@ -0,0 +1,30 @@
+#ifndef ICEDAEMON_H
+#define ICEDAEMON_H
+
+#include <daemon.h>
+#include "iceModule.h"
+
+class IceDaemon : public Daemon {
+ public:
+ IceDaemon(int & argc, char ** argv);
+ virtual ~IceDaemon();
+
+ void run() const;
+ void shutdown() const;
+
+ void executeTask(const std::string & name, const ParamMap & params) const;
+ void executeView(const std::string & name, RowSetPresenterPtr p, const ParamMap & params) const;
+
+ INITOPTIONS;
+ static std::string adapterName;
+ static std::string adapterEndpoint;
+ static std::string interface;
+ static std::string slice;
+ static std::string viewRoot;
+ static std::string taskRoot;
+
+ private:
+ Ice::CommunicatorPtr ic;
+};
+
+#endif
diff --git a/project2/ice/iceDataSource.cpp b/project2/ice/iceDataSource.cpp
new file mode 100644
index 0000000..5cfd5b1
--- /dev/null
+++ b/project2/ice/iceDataSource.cpp
@@ -0,0 +1,43 @@
+#include <pch.hpp>
+#include "iceDataSource.h"
+#include "buildComms.h"
+#include "buildShared.h"
+#include "buildClient.h"
+#include <Ice/Ice.h>
+
+IceDataSource::Libs IceDataSource::libs;
+IceDataSource::Proxies IceDataSource::proxies;
+
+DECLARE_OPTIONS(IceDataSource, "ICE Data Source")
+("ice.client.slice", Options::functions(boost::bind(&IceDataSource::SetSlice, _1), boost::bind(&IceDataSource::ClearSlice)),
+ "The ICE Slice file(s) to compile")
+END_OPTIONS(IceDataSource);
+
+int dummy = 0;
+IceDataSource::IceDataSource(ScriptNodePtr p) :
+ DataSource(p),
+ endpoint(p, "endpoint"),
+ ic(Ice::initialize(dummy, NULL))
+{
+}
+
+void
+IceDataSource::SetSlice(const VariableType & vslice)
+{
+ auto slice = vslice.as<std::string>();
+ BuildComms bc(slice);
+ BuildShared bcs(slice, { &bc });
+ BuildClient bcl(slice, { &bcs });
+ bcl.Update();
+ libs.insert({ slice, bcl.Open() });
+}
+
+void
+IceDataSource::ClearSlice()
+{
+ libs.clear();
+ proxies.clear();
+}
+
+DECLARE_LOADER("icedatasource", IceDataSource);
+
diff --git a/project2/ice/iceDataSource.h b/project2/ice/iceDataSource.h
new file mode 100644
index 0000000..e80a3fc
--- /dev/null
+++ b/project2/ice/iceDataSource.h
@@ -0,0 +1,43 @@
+#ifndef ICEDATASOURCE_H
+#define ICEDATASOURCE_H
+
+#include <dataSource.h>
+#include <options.h>
+#include <variables.h>
+#include "iceCompile.h"
+#include <Ice/Communicator.h>
+
+class IceDataSource : public DataSource {
+ public:
+ INITOPTIONS;
+ static std::string slice;
+
+ IceDataSource(ScriptNodePtr p);
+
+ template <typename Interface>
+ Interface GetProxy(const std::string object, ExecContext * ec) const
+ {
+ auto existingProxy = proxies.find(object);
+ if (existingProxy == proxies.end()) {
+ auto prx = Interface::checkedCast(ic->stringToProxy(object + ":" + endpoint(ec).as<std::string>()));
+ existingProxy = proxies.insert({ object, prx }).first;
+ return prx;
+ }
+ return Interface::checkedCast(existingProxy->second);
+ }
+
+ private:
+ static void SetSlice(const VariableType &);
+ static void ClearSlice();
+ typedef std::map<std::string, IceCompile::LibHandle> Libs;
+ static Libs libs;
+
+ const Variable endpoint;
+
+ const Ice::CommunicatorPtr ic;
+ typedef std::map<std::string, Ice::ObjectPrx> Proxies;
+ static Proxies proxies;
+};
+
+#endif
+
diff --git a/project2/ice/iceModule.cpp b/project2/ice/iceModule.cpp
new file mode 100644
index 0000000..1738bef
--- /dev/null
+++ b/project2/ice/iceModule.cpp
@@ -0,0 +1,22 @@
+#include <pch.hpp>
+#include "iceModule.h"
+#include "iceDaemon.h"
+#include "instanceStore.impl.h"
+
+IceDaemonModule::IceDaemonModule(const IceDaemon * id) :
+ iceDaemon(id)
+{
+}
+
+void
+IceDaemonModule::executeView(const std::string & name, RowSetPresenterPtr p, const ParamMap & params) const {
+ iceDaemon->executeView(name, p, params);
+}
+
+void
+IceDaemonModule::executeTask(const std::string & name, const ParamMap & params) const {
+ iceDaemon->executeTask(name, params);
+}
+
+INSTANTIATESTORE(std::string, IceDaemonAdapterHandlerLoader);
+
diff --git a/project2/ice/iceModule.h b/project2/ice/iceModule.h
new file mode 100644
index 0000000..246c9b8
--- /dev/null
+++ b/project2/ice/iceModule.h
@@ -0,0 +1,70 @@
+#ifndef ICEMODULE_H
+#define ICEMODULE_H
+
+#include <map>
+#include <variableType.h>
+#include <Ice/Ice.h>
+#include <presenter.h>
+#include <safeMapFind.h>
+#include <boost/function.hpp>
+
+typedef std::map<std::string, VariableType> ParamMap;
+class IceDaemon;
+
+class IceDaemonModule {
+ protected:
+ IceDaemonModule(const IceDaemon *);
+
+ void executeTask(const std::string & name, const ParamMap & params) const;
+ void executeView(const std::string & name, RowSetPresenterPtr p, const ParamMap & params) const;
+
+ private:
+ const IceDaemon * const iceDaemon;
+};
+
+class IceDaemonAdapterHandler : public IntrusivePtrBase {
+ public:
+ virtual void add(Ice::ObjectAdapterPtr, const IceDaemon *, Ice::CommunicatorPtr) const = 0;
+ virtual void remove(Ice::ObjectAdapterPtr, Ice::CommunicatorPtr) const = 0;
+};
+
+typedef boost::intrusive_ptr<IceDaemonAdapterHandler> IceDaemonAdapterHandlerPtr;
+typedef GenLoader<IceDaemonAdapterHandler, std::string> IceDaemonAdapterHandlerLoader;
+
+template <typename IC>
+class IcePresenter : public RowSetPresenter {
+ public:
+ typedef boost::function<void (typename IC::value_type *, const VariableType &)> TargetAssigner;
+ typedef std::map<Glib::ustring, TargetAssigner> MemberTargets;
+ SimpleMessageException(NoSuchMember);
+
+ IcePresenter(IC & t);
+ virtual void addNamedValue(const Glib::ustring & member, const VariableType & value) const
+ {
+ safeMapLookup<NoSuchMember>(memberTargets, member)(&*current, value);
+ }
+ virtual void addNewRow(const Glib::ustring&) const
+ {
+ target.push_back(typename IC::value_type());
+ }
+ virtual void finishRow() const
+ {
+ current = target.end();
+ }
+ // The target array already exists, so these need not do anything
+ virtual void addNewArray(const Glib::ustring&, bool) const { }
+ virtual void finishArray(bool) const { }
+ virtual void init() { }
+ private:
+ IC & target;
+ mutable typename IC::iterator current;
+ const MemberTargets memberTargets;
+
+ template <typename T, typename M> static void memberAssign(T * t, M T::*m, const VariableType & v) {
+ t->*m = v.as<M>();
+ }
+};
+
+
+#endif
+
diff --git a/project2/ice/iceRows.h b/project2/ice/iceRows.h
new file mode 100644
index 0000000..654de50
--- /dev/null
+++ b/project2/ice/iceRows.h
@@ -0,0 +1,87 @@
+#ifndef ICEVIEW_H
+#define ICEVIEW_H
+
+#include <rowSet.h>
+#include "iceConvert.h"
+#include "iceClient.h"
+
+template <typename Type>
+class IceRowState : public RowState {
+ public:
+ IceRowState()
+ {
+ unsigned int idx = 0;
+ IceType<Type>::CreateColumns(boost::bind(&IceRowState::AddColumn, this, boost::ref(idx), _1));
+ fields.resize(columns.size());
+ }
+
+ void AddColumn(unsigned int & c, const std::string & name)
+ {
+ columns.insert(new Column(c++, name));
+ }
+
+ const Columns & getColumns() const { return columns; }
+
+ void IterateOver(const Type & record, const RowProcessorCallback & rp) {
+ auto field = fields.begin();
+ IceType<Type>::ForEachDataMember(record, boost::bind(&IceRowState::AssignFieldValue, this, boost::ref(field), _1));
+ this->process(rp);
+ }
+
+ void AssignFieldValue(FieldValues::iterator & field, const VariableType & vt)
+ {
+ *field++ = vt;
+ }
+
+ Columns columns;
+};
+
+template <typename Type>
+class IceRowState<std::vector<Type> > : public RowState {
+ public:
+ typedef std::vector<Type> RangeType;
+ IceRowState()
+ {
+ unsigned int idx = 0;
+ IceType<Type>::CreateColumns(boost::bind(&IceRowState::AddColumn, this, boost::ref(idx), _1));
+ fields.resize(columns.size());
+ }
+
+ void AddColumn(unsigned int & c, const std::string & name)
+ {
+ columns.insert(new Column(c++, name));
+ }
+
+ const Columns & getColumns() const { return columns; }
+
+ void IterateOver(const RangeType & records, const RowProcessorCallback & rp) {
+ BOOST_FOREACH(const auto & record, records) {
+ auto field = fields.begin();
+ IceType<Type>::ForEachDataMember(record, boost::bind(&IceRowState::AssignFieldValue, this, boost::ref(field), _1));
+ this->process(rp);
+ }
+ }
+
+ void AssignFieldValue(FieldValues::iterator & field, const VariableType & vt)
+ {
+ *field++ = vt;
+ }
+
+ Columns columns;
+};
+
+template <typename Interface>
+class IceRows : public RowSet, public IceClient<Interface> {
+ public:
+ IceRows(ScriptNodePtr p) :
+ RowSet(p),
+ IceClient<Interface>(p)
+ {
+ }
+ void loadComplete(const CommonObjects * co) {
+ IceClient<Interface>::loadComplete(co);
+ }
+};
+
+#endif
+
diff --git a/project2/ice/iceTask.h b/project2/ice/iceTask.h
new file mode 100644
index 0000000..2d71818
--- /dev/null
+++ b/project2/ice/iceTask.h
@@ -0,0 +1,22 @@
+#ifndef ICETASK_H
+#define ICETASK_H
+
+#include <task.h>
+#include <logger.h>
+#include "iceClient.h"
+
+template <typename Interface>
+class IceTask : public Task, public IceClient<Interface> {
+ public:
+ IceTask(ScriptNodePtr p) :
+ SourceObject(p),
+ Task(p),
+ IceClient<Interface>(p)
+ {
+ }
+
+ void loadComplete(const CommonObjects * co) { IceClient<Interface>::loadComplete(co); }
+};
+
+#endif
+
diff --git a/project2/ice/pch.hpp b/project2/ice/pch.hpp
new file mode 100644
index 0000000..c74eebf
--- /dev/null
+++ b/project2/ice/pch.hpp
@@ -0,0 +1,21 @@
+#ifdef BOOST_BUILD_PCH_ENABLED
+#ifndef CGI_PCH
+#define CGI_PCH
+
+#include <Ice/Ice.h>
+#include <boost/filesystem.hpp>
+#include <boost/foreach.hpp>
+#include <boost/function.hpp>
+#include <boost/optional.hpp>
+#include <commonObjects.h>
+#include <exceptions.h>
+#include <logger.h>
+#include <map>
+#include <options.h>
+#include <Slice/Parser.h>
+#include <string>
+#include <variables.h>
+
+#endif
+#endif
+
diff --git a/project2/ice/slice2Daemon.cpp b/project2/ice/slice2Daemon.cpp
new file mode 100644
index 0000000..6a8e5fa
--- /dev/null
+++ b/project2/ice/slice2Daemon.cpp
@@ -0,0 +1,86 @@
+#include <pch.hpp>
+#include "slice2Daemon.h"
+#include <boost/foreach.hpp>
+#include <Slice/CPlusPlusUtil.h>
+
+Slice2Daemon::Slice2Daemon(FILE * c) :
+ code(c)
+{
+}
+
+bool
+Slice2Daemon::visitModuleStart(const Slice::ModulePtr & m)
+{
+ module = m->name();
+ fprintf(code, "namespace %s {\n", m->name().c_str());
+ return true;
+}
+
+bool
+Slice2Daemon::visitClassDefStart(const Slice::ClassDefPtr & c)
+{
+ interface = c->name();
+ fprintf(code, "\tclass %sImpl : public IceDaemonModule, public %s {\n", c->name().c_str(), c->name().c_str());
+ fprintf(code, "\t\tpublic:\n");
+ fprintf(code, "\t\t\t%sImpl(const IceDaemon * id) :\n", c->name().c_str());
+ fprintf(code, "\t\t\t\tIceDaemonModule(id)\n");
+ fprintf(code, "\t\t\t{\n\t\t\t}\n\n");
+ return true;
+}
+
+void
+Slice2Daemon::visitOperation(const Slice::OperationPtr & o)
+{
+ if (o->returnType()) {
+ fprintf(code, "\t\t\t%s %s(", returnTypeToString(o->returnType(), o->returnIsOptional()).c_str(), o->name().c_str());
+ }
+ else {
+ fprintf(code, "\t\t\tvoid %s(", o->name().c_str());
+ }
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, "%s %s, ", inputTypeToString(p->type(), p->optional(), p->getMetaData(), 0).c_str(), p->name().c_str());
+ }
+ fprintf(code, "const ::Ice::Current &) {\n");
+ visitParameterMap(o);
+ if (o->returnType()) {
+ fprintf(code, "\t\t\t\t%s rtn;\n", o->returnType()->typeId().c_str());
+ fprintf(code, "\t\t\t\tRowSetPresenterPtr ipp = new IcePresenter< %s >(rtn);\n", o->returnType()->typeId().c_str());
+ fprintf(code, "\t\t\t\texecuteView(\"%s/%s/%s\", ipp, params);\n", module.c_str(), interface.c_str(), o->name().c_str());
+ fprintf(code, "\t\t\t\treturn rtn;\n");
+ }
+ else {
+ fprintf(code, "\t\t\t\texecuteTask(\"%s/%s/%s\", params);\n", module.c_str(), interface.c_str(), o->name().c_str());
+ }
+ fprintf(code, "\t\t\t}\n\n");
+}
+
+void
+Slice2Daemon::visitClassDefEnd(const Slice::ClassDefPtr & c)
+{
+ fprintf(code, "\t}; // class %sImpl\n\n", c->name().c_str());
+}
+
+void
+Slice2Daemon::visitModuleEnd(const Slice::ModulePtr & m)
+{
+ fprintf(code, "}; // namespace %s\n\n", m->name().c_str());
+}
+
+void
+Slice2Daemon::visitParameterMap(const Slice::OperationPtr & o)
+{
+ fprintf(code, "\t\t\t\tParamMap params {\n");
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ Slice::StructPtr s = dynamic_cast<Slice::Struct *>(p->type().get());
+ if (s) {
+ BOOST_FOREACH(const auto & m, s->dataMembers()) {
+ fprintf(code, "\t\t\t\t\t\t{\"%s.%s\", %s.%s},\n", p->name().c_str(), m->name().c_str(), p->name().c_str(), m->name().c_str());
+ }
+ }
+ else {
+ fprintf(code, "\t\t\t\t\t\t{\"%s\", %s},\n", p->name().c_str(), p->name().c_str());
+ }
+ }
+ fprintf(code, "\t\t\t\t\t};\n");
+}
+
diff --git a/project2/ice/slice2Daemon.h b/project2/ice/slice2Daemon.h
new file mode 100644
index 0000000..4487f9b
--- /dev/null
+++ b/project2/ice/slice2Daemon.h
@@ -0,0 +1,24 @@
+#ifndef ICEBUILDDAEMON_H
+#define ICEBUILDDAEMON_H
+
+#include <Slice/Parser.h>
+
+class Slice2Daemon : public Slice::ParserVisitor {
+ public:
+ Slice2Daemon(FILE * c);
+
+ virtual bool visitModuleStart(const Slice::ModulePtr & m);
+ virtual bool visitClassDefStart(const Slice::ClassDefPtr & c);
+ virtual void visitOperation(const Slice::OperationPtr & o);
+ virtual void visitClassDefEnd(const Slice::ClassDefPtr & c);
+ virtual void visitModuleEnd(const Slice::ModulePtr & m);
+
+ private:
+ void visitParameterMap(const Slice::OperationPtr & o);
+ FILE * code;
+ std::string interface;
+ std::string module;
+};
+
+#endif
+
diff --git a/project2/ice/slice2DaemonLoader.cpp b/project2/ice/slice2DaemonLoader.cpp
new file mode 100644
index 0000000..81fd501
--- /dev/null
+++ b/project2/ice/slice2DaemonLoader.cpp
@@ -0,0 +1,46 @@
+#include <pch.hpp>
+#include "slice2DaemonLoader.h"
+#include <boost/foreach.hpp>
+
+Slice2DaemonLoader::Slice2DaemonLoader(FILE * c) :
+ code(c)
+{
+}
+
+bool
+Slice2DaemonLoader::visitModuleStart(const Slice::ModulePtr & m)
+{
+ module = m->name();
+ fprintf(code, "// Loader for %s\n", m->name().c_str());
+ fprintf(code, "class %sIceDaemonAdapterHandler : public IceDaemonAdapterHandler {\n", m->name().c_str());
+ fprintf(code, "\tpublic:\n");
+ return true;
+}
+
+bool
+Slice2DaemonLoader::visitClassDefStart(const Slice::ClassDefPtr & c)
+{
+ interfaces.push_back(c->name());
+ return false;
+}
+
+void
+Slice2DaemonLoader::visitModuleEnd(const Slice::ModulePtr & m)
+{
+ fprintf(code, "\t\tvoid add(Ice::ObjectAdapterPtr adapter, const IceDaemon * id, Ice::CommunicatorPtr ic) const {\n");
+ BOOST_FOREACH(const auto & i, interfaces) {
+ fprintf(code, "\t\t\tadapter->add(new %s::%sImpl(id), ic->stringToIdentity(\"%s%s\"));\n",
+ module.c_str(), i.c_str(), module.c_str(), i.c_str());
+ }
+ fprintf(code, "\t\t}\n\n");
+ fprintf(code, "\t\tvoid remove(Ice::ObjectAdapterPtr adapter, Ice::CommunicatorPtr ic) const {\n");
+ BOOST_FOREACH(const auto & i, interfaces) {
+ fprintf(code, "\t\t\tadapter->remove(ic->stringToIdentity(\"%s%s\"));\n",
+ module.c_str(), i.c_str());
+ }
+ fprintf(code, "\t\t}\n\n");
+ fprintf(code, "};\n");
+ fprintf(code, "DECLARE_GENERIC_LOADER(\"%s\", IceDaemonAdapterHandlerLoader, %sIceDaemonAdapterHandler);\n", m->name().c_str(), m->name().c_str());
+ fprintf(code, "// End loader for%s\n\n", m->name().c_str());
+}
+
diff --git a/project2/ice/slice2DaemonLoader.h b/project2/ice/slice2DaemonLoader.h
new file mode 100644
index 0000000..3c1fd5f
--- /dev/null
+++ b/project2/ice/slice2DaemonLoader.h
@@ -0,0 +1,21 @@
+#ifndef ICEBUILDLOADER_H
+#define ICEBUILDLOADER_H
+
+#include <Slice/Parser.h>
+
+class Slice2DaemonLoader : public Slice::ParserVisitor {
+ public:
+ Slice2DaemonLoader(FILE * c);
+
+ virtual bool visitModuleStart(const Slice::ModulePtr & m);
+ virtual bool visitClassDefStart(const Slice::ClassDefPtr & c);
+ virtual void visitModuleEnd(const Slice::ModulePtr & m);
+
+ private:
+ FILE * code;
+ std::string module;
+ std::vector<std::string> interfaces;
+};
+
+#endif
+
diff --git a/project2/ice/slice2Presenter.cpp b/project2/ice/slice2Presenter.cpp
new file mode 100644
index 0000000..3cfb422
--- /dev/null
+++ b/project2/ice/slice2Presenter.cpp
@@ -0,0 +1,60 @@
+#include <pch.hpp>
+#include "slice2Presenter.h"
+#include <Slice/CPlusPlusUtil.h>
+
+Slice2Presenter::Slice2Presenter(FILE * c) :
+ code(c)
+{
+}
+
+bool
+Slice2Presenter::visitModuleStart(const Slice::ModulePtr & m)
+{
+ module = m->name();
+ fprintf(code, "// Specialized functions for IcePresenters in module %s\n\n", module.c_str());
+ return true;
+}
+
+void
+Slice2Presenter::visitModuleEnd(const Slice::ModulePtr &)
+{
+ fprintf(code, "// End Specialized functions for IcePresenters in module %s\n\n", module.c_str());
+ module.clear();
+}
+
+bool
+Slice2Presenter::visitStructStart(const Slice::StructPtr & s)
+{
+ strct = s->name();
+ fprintf(code, "template <>\nIcePresenter<std::vector< %s::%s >>::IcePresenter(std::vector< %s::%s > & t) :\n",
+ module.c_str(), s->name().c_str(),
+ module.c_str(), s->name().c_str());
+ fprintf(code, "\ttarget(t),\n\tcurrent(target.end()),\n");
+ fprintf(code, "\tmemberTargets({\n");
+ return true;
+}
+
+void
+Slice2Presenter::visitDataMember(const Slice::DataMemberPtr & m)
+{
+ fprintf(code, "\t\t{\"%s\", boost::bind(&IcePresenter<std::vector< %s::%s >>::memberAssign< %s::%s, %s >, _1, &%s::%s::%s, _2)},\n",
+ m->name().c_str(),
+ module.c_str(), strct.c_str(),
+ module.c_str(), strct.c_str(),
+ typeToString(m->type()).c_str(),
+ module.c_str(), strct.c_str(), m->name().c_str()
+
+ );
+}
+
+void
+Slice2Presenter::visitStructEnd(const Slice::StructPtr&)
+{
+ fprintf(code, "\t})\n{\n");
+
+ //fprintf(code, "boost::bind(&IcePresenter<std::vector<P2TV::Recording>>::memberAssign<P2TV::Recording, int>, NULL, &P2TV::Recording::recordingId, 1);\n");
+
+ fprintf(code, "}\n\n");
+ strct.clear();
+}
+
diff --git a/project2/ice/slice2Presenter.h b/project2/ice/slice2Presenter.h
new file mode 100644
index 0000000..892f2c1
--- /dev/null
+++ b/project2/ice/slice2Presenter.h
@@ -0,0 +1,23 @@
+#ifndef ICEBUILDPRESENTER_H
+#define ICEBUILDPRESENTER_H
+
+#include <Slice/Parser.h>
+
+class Slice2Presenter : public Slice::ParserVisitor {
+ public:
+ Slice2Presenter(FILE * c);
+ virtual bool visitModuleStart(const Slice::ModulePtr & m);
+ virtual void visitModuleEnd(const Slice::ModulePtr & m);
+ virtual bool visitStructStart(const Slice::StructPtr&);
+ virtual void visitStructEnd(const Slice::StructPtr&);
+ virtual void visitDataMember(const Slice::DataMemberPtr&);
+
+ private:
+ FILE * code;
+ std::string module;
+ std::string strct;
+};
+
+#endif
+
+
diff --git a/project2/ice/slice2Rows.cpp b/project2/ice/slice2Rows.cpp
new file mode 100644
index 0000000..9646f17
--- /dev/null
+++ b/project2/ice/slice2Rows.cpp
@@ -0,0 +1,94 @@
+#include <pch.hpp>
+#include "slice2Rows.h"
+#include <boost/foreach.hpp>
+#include <Slice/CPlusPlusUtil.h>
+
+Slice2Rows::Slice2Rows(FILE * c) :
+ code(c)
+{
+}
+
+bool
+Slice2Rows::visitModuleStart(const Slice::ModulePtr & m)
+{
+ module = m->name();
+ fprintf(code, "namespace IceRowsWrappers {\n");
+ fprintf(code, "\tnamespace %s {\n", m->name().c_str());
+ return true;
+}
+
+bool
+Slice2Rows::visitClassDefStart(const Slice::ClassDefPtr & c)
+{
+ interface = c->name();
+ fprintf(code, "\t\tnamespace %s {\n", c->name().c_str());
+ return true;
+}
+
+void
+Slice2Rows::visitOperation(const Slice::OperationPtr & o)
+{
+ if (o->hasMetaData("project2:rows")) {
+ fprintf(code, "\t\t\tclass %s : public IceRows< ::%s::%sPrx > {\n", o->name().c_str(), module.c_str(), interface.c_str());
+ fprintf(code, "\t\t\t\tpublic:\n");
+ // Constructor
+ fprintf(code, "\t\t\t\t\t%s(ScriptNodePtr p) :\n", o->name().c_str());
+ fprintf(code, "\t\t\t\t\t\tIceRows< ::%s::%sPrx >(p)", module.c_str(), interface.c_str());
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, ",\n\t\t\t\t\t\t%s(p, \"%s\")", p->name().c_str(), p->name().c_str());
+ }
+ fprintf(code, "\n\t\t\t\t\t{\n");
+ fprintf(code, "\t\t\t\t\t}\n\n");
+ // Execute
+ fprintf(code, "\t\t\t\t\tvoid execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const\n");
+ fprintf(code, "\t\t\t\t\t{\n");
+ fprintf(code, "\t\t\t\t\t\tLogger()->messagebf(LOG_DEBUG, \"%%s: ");
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, "%s = %%s, ", p->name().c_str());
+ }
+ fprintf(code, "ice @ %%p\", \n");
+ fprintf(code, "\t\t\t\t\t\t\t\t__PRETTY_FUNCTION__, ");
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, "%s(ec).as<std::string>(), ", p->name().c_str());
+ }
+ fprintf(code, "ice);\n");
+ fprintf(code, "\t\t\t\t\t\tIce::Context ctx;\n");
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, "\t\t\t\t\t\tauto _%s = IceConvert< %s >::FromVariable(%s(ec));\n",
+ p->name().c_str(),
+ Slice::typeToString(p->type()).c_str(),
+ p->name().c_str());
+ }
+ fprintf(code, "\t\t\t\t\t\tIceRowState<decltype(service->%s(", o->name().c_str());
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, "_%s, ", p->name().c_str());
+ }
+ fprintf(code, "ctx))> irs;\n");
+ fprintf(code, "\t\t\t\t\t\tirs.IterateOver(service->%s(", o->name().c_str());
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, "_%s, ", p->name().c_str());
+ }
+ fprintf(code, "ctx), rp);\n");
+ fprintf(code, "\t\t\t\t\t}\n\n");
+ // Parameter variables
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, "\t\t\t\t\tconst Variable %s;\n", p->name().c_str());
+ }
+ fprintf(code, "\t\t\t};\n");
+ fprintf(code, "\t\t\tDECLARE_LOADER(\"%s-%s-%s\", %s);\n\n", module.c_str(), interface.c_str(), o->name().c_str(), o->name().c_str());
+ }
+}
+
+void
+Slice2Rows::visitClassDefEnd(const Slice::ClassDefPtr & c)
+{
+ fprintf(code, "\t\t} // namespace %s\n\n", c->name().c_str());
+}
+
+void
+Slice2Rows::visitModuleEnd(const Slice::ModulePtr & m)
+{
+ fprintf(code, "\t}; // namespace %s\n", m->name().c_str());
+ fprintf(code, "}; // namespace IceRowsWrappers\n\n");
+}
+
diff --git a/project2/ice/slice2Rows.h b/project2/ice/slice2Rows.h
new file mode 100644
index 0000000..b97f009
--- /dev/null
+++ b/project2/ice/slice2Rows.h
@@ -0,0 +1,24 @@
+#ifndef ICEBUILDVIEW_H
+#define ICEBUILDVIEW_H
+
+#include <Slice/Parser.h>
+
+class Slice2Rows : public Slice::ParserVisitor {
+ public:
+ Slice2Rows(FILE * c);
+ virtual bool visitModuleStart(const Slice::ModulePtr & m);
+ virtual bool visitClassDefStart(const Slice::ClassDefPtr & c);
+ virtual void visitOperation(const Slice::OperationPtr & o);
+ virtual void visitClassDefEnd(const Slice::ClassDefPtr & c);
+ virtual void visitModuleEnd(const Slice::ModulePtr & m);
+
+ private:
+ FILE * code;
+ std::string interface;
+ std::string module;
+};
+
+#endif
+
+
+
diff --git a/project2/ice/slice2Task.cpp b/project2/ice/slice2Task.cpp
new file mode 100644
index 0000000..53ad8b4
--- /dev/null
+++ b/project2/ice/slice2Task.cpp
@@ -0,0 +1,86 @@
+#include <pch.hpp>
+#include "slice2Task.h"
+#include <boost/foreach.hpp>
+#include <Slice/CPlusPlusUtil.h>
+
+Slice2Task::Slice2Task(FILE * c) :
+ code(c)
+{
+}
+
+bool
+Slice2Task::visitModuleStart(const Slice::ModulePtr & m)
+{
+ module = m->name();
+ fprintf(code, "namespace IceTaskWrappers {\n");
+ fprintf(code, "\tnamespace %s {\n", m->name().c_str());
+ return true;
+}
+
+bool
+Slice2Task::visitClassDefStart(const Slice::ClassDefPtr & c)
+{
+ interface = c->name();
+ fprintf(code, "\t\tnamespace %s {\n", c->name().c_str());
+ return true;
+}
+
+void
+Slice2Task::visitOperation(const Slice::OperationPtr & o)
+{
+ if (o->hasMetaData("project2:task")) {
+ fprintf(code, "\t\t\tclass %s : public IceTask< ::%s::%sPrx > {\n", o->name().c_str(), module.c_str(), interface.c_str());
+ fprintf(code, "\t\t\t\tpublic:\n");
+ // Constructor
+ fprintf(code, "\t\t\t\t\t%s(ScriptNodePtr p) :\n", o->name().c_str());
+ fprintf(code, "\t\t\t\t\t\tSourceObject(p),\n");
+ fprintf(code, "\t\t\t\t\t\tIceTask< ::%s::%sPrx >(p)", module.c_str(), interface.c_str());
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, ",\n\t\t\t\t\t\t%s(p, \"%s\")", p->name().c_str(), p->name().c_str());
+ }
+ fprintf(code, "\n\t\t\t\t\t{\n");
+ fprintf(code, "\t\t\t\t\t}\n\n");
+ // Execute
+ fprintf(code, "\t\t\t\t\tvoid execute(ExecContext * ec) const\n");
+ fprintf(code, "\t\t\t\t\t{\n");
+ fprintf(code, "\t\t\t\t\t\tLogger()->messagebf(LOG_DEBUG, \"%%s: ");
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, "%s = %%s, ", p->name().c_str());
+ }
+ fprintf(code, "ice @ %%p\", \n");
+ fprintf(code, "\t\t\t\t\t\t\t\t__PRETTY_FUNCTION__, ");
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, "%s(ec).as<std::string>(), ", p->name().c_str());
+ }
+ fprintf(code, "ice);\n");
+ fprintf(code, "\t\t\t\t\t\tIce::Context ctx;\n");
+ fprintf(code, "\t\t\t\t\t\tservice->%s(", o->name().c_str());
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, "IceConvert< %s >::ToVariable(%s(ec)), ",
+ Slice::typeToString(p->type()).c_str(),
+ p->name().c_str());
+ }
+ fprintf(code, "ctx);\n");
+ fprintf(code, "\t\t\t\t\t}\n\n");
+ // Parameter variables
+ BOOST_FOREACH(const auto & p, o->parameters()) {
+ fprintf(code, "\t\t\t\t\tconst Variable %s;\n", p->name().c_str());
+ }
+ fprintf(code, "\t\t\t};\n");
+ fprintf(code, "\t\t\tDECLARE_LOADER(\"%s-%s-%s\", %s);\n\n", module.c_str(), interface.c_str(), o->name().c_str(), o->name().c_str());
+ }
+}
+
+void
+Slice2Task::visitClassDefEnd(const Slice::ClassDefPtr & c)
+{
+ fprintf(code, "\t\t} // namespace %s\n\n", c->name().c_str());
+}
+
+void
+Slice2Task::visitModuleEnd(const Slice::ModulePtr & m)
+{
+ fprintf(code, "\t}; // namespace %s\n", m->name().c_str());
+ fprintf(code, "}; // namespace IceTaskWrappers\n\n");
+}
+
diff --git a/project2/ice/slice2Task.h b/project2/ice/slice2Task.h
new file mode 100644
index 0000000..d3bd0fe
--- /dev/null
+++ b/project2/ice/slice2Task.h
@@ -0,0 +1,24 @@
+#ifndef SLICE2TASK_H
+#define SLICE2TASK_H
+
+#include <Slice/Parser.h>
+
+class Slice2Task : public Slice::ParserVisitor {
+ public:
+ Slice2Task(FILE * c);
+
+ virtual bool visitModuleStart(const Slice::ModulePtr & m);
+ virtual bool visitClassDefStart(const Slice::ClassDefPtr & c);
+ virtual void visitOperation(const Slice::OperationPtr & o);
+ virtual void visitClassDefEnd(const Slice::ClassDefPtr & c);
+ virtual void visitModuleEnd(const Slice::ModulePtr & m);
+
+ private:
+ FILE * code;
+ std::string interface;
+ std::string module;
+};
+
+#endif
+
+
diff --git a/project2/ice/slice2Type.cpp b/project2/ice/slice2Type.cpp
new file mode 100644
index 0000000..9c3404e
--- /dev/null
+++ b/project2/ice/slice2Type.cpp
@@ -0,0 +1,110 @@
+#include <pch.hpp>
+#include "slice2Type.h"
+#include <Slice/CPlusPlusUtil.h>
+#include <boost/foreach.hpp>
+
+Slice2Type::Slice2Type(FILE * c) :
+ code(c)
+{
+}
+
+bool
+Slice2Type::visitModuleStart(const Slice::ModulePtr & m)
+{
+ module = m->name();
+ return true;
+}
+
+void
+Slice2Type::visitModuleEnd(const Slice::ModulePtr &)
+{
+ module.clear();
+}
+
+void
+Slice2Type::visitClassDecl(const Slice::ClassDeclPtr&)
+{
+}
+
+bool
+Slice2Type::visitExceptionStart(const Slice::ExceptionPtr & e)
+{
+ if (e->hasMetaData("project2:type")) {
+ fprintf(code, "template <>\nvoid IceType< %s::%s >::ForEachDataMember(const %s::%s & obj, const IceEachDataMemberValue & func)\n{\n",
+ module.c_str(), e->name().c_str(),
+ module.c_str(), e->name().c_str());
+ membersToVariables(e->dataMembers(), "obj.");
+ fprintf(code, "}\n\n");
+
+ fprintf(code, "template <>\nvoid IceType< %s::%s >::CreateColumns(const IceEachDataMemberName & func)\n{\n",
+ module.c_str(), e->name().c_str());
+ membersToColumns(e->dataMembers());
+ fprintf(code, "}\n\n");
+ }
+ return false;
+}
+
+bool
+Slice2Type::visitClassDefStart(const Slice::ClassDefPtr & c)
+{
+ if (c->hasMetaData("project2:type")) {
+ fprintf(code, "template <>\nvoid IceType< IceInternal::Handle< %s::%s > >::ForEachDataMember(const IceInternal::Handle< %s::%s > & ptr, const IceEachDataMemberValue & func)\n{\n",
+ module.c_str(), c->name().c_str(),
+ module.c_str(), c->name().c_str());
+ membersToVariables(c->dataMembers(), "ptr->");
+ fprintf(code, "}\n\n");
+
+ fprintf(code, "template <>\nvoid IceType< IceInternal::Handle< %s::%s > >::CreateColumns(const IceEachDataMemberName & func)\n{\n",
+ module.c_str(), c->name().c_str());
+ membersToColumns(c->dataMembers());
+ fprintf(code, "}\n\n");
+ }
+ return false;
+}
+
+bool
+Slice2Type::visitStructStart(const Slice::StructPtr & s)
+{
+ if (s->hasMetaData("project2:type")) {
+ fprintf(code, "template <>\nvoid IceType< %s::%s >::ForEachDataMember(const %s::%s & obj, const IceEachDataMemberValue & func)\n{\n",
+ module.c_str(), s->name().c_str(),
+ module.c_str(), s->name().c_str());
+ membersToVariables(s->dataMembers(), "obj.");
+ fprintf(code, "}\n\n");
+
+ fprintf(code, "template <>\nvoid IceType< %s::%s >::CreateColumns(const IceEachDataMemberName & func)\n{\n",
+ module.c_str(), s->name().c_str());
+ membersToColumns(s->dataMembers());
+ fprintf(code, "}\n\n");
+ }
+ return false;
+}
+
+void
+Slice2Type::membersToVariables(const Slice::DataMemberList & members, const std::string & access) const
+{
+ BOOST_FOREACH(const auto & m, members) {
+ if (m->optional()) {
+ fprintf(code, "\tfunc(IceConvert< IceUtil::Optional< %s> >::ToVariable(%s%s));\n",
+ Slice::typeToString(m->type()).c_str(),
+ access.c_str(),
+ m->name().c_str());
+ }
+ else {
+ fprintf(code, "\tfunc(IceConvert< %s >::ToVariable(%s%s));\n",
+ Slice::typeToString(m->type()).c_str(),
+ access.c_str(),
+ m->name().c_str());
+ }
+ }
+}
+
+void
+Slice2Type::membersToColumns(const Slice::DataMemberList & members) const
+{
+ BOOST_FOREACH(const auto & m, members) {
+ fprintf(code, "\tfunc(\"%s\");\n",
+ m->name().c_str());
+ }
+}
+
diff --git a/project2/ice/slice2Type.h b/project2/ice/slice2Type.h
new file mode 100644
index 0000000..e2b94fc
--- /dev/null
+++ b/project2/ice/slice2Type.h
@@ -0,0 +1,25 @@
+#ifndef ICEBUILDPRESENTER_H
+#define ICEBUILDPRESENTER_H
+
+#include <Slice/Parser.h>
+
+class Slice2Type : public Slice::ParserVisitor {
+ public:
+ Slice2Type(FILE * c);
+ virtual bool visitModuleStart(const Slice::ModulePtr & m);
+ virtual void visitModuleEnd(const Slice::ModulePtr & m);
+ virtual void visitClassDecl(const Slice::ClassDeclPtr&);
+ virtual bool visitExceptionStart(const Slice::ExceptionPtr&);
+ virtual bool visitClassDefStart(const Slice::ClassDefPtr&);
+ virtual bool visitStructStart(const Slice::StructPtr&);
+
+ private:
+ void membersToVariables(const Slice::DataMemberList &, const std::string &) const;
+ void membersToColumns(const Slice::DataMemberList &) const;
+ FILE * code;
+ std::string module;
+};
+
+#endif
+
+
diff --git a/project2/ice/sliceCompile.cpp b/project2/ice/sliceCompile.cpp
new file mode 100644
index 0000000..f98ecde
--- /dev/null
+++ b/project2/ice/sliceCompile.cpp
@@ -0,0 +1,59 @@
+#include <pch.hpp>
+#include "sliceCompile.h"
+#include <scopeObject.h>
+
+SliceCompile::SliceCompile(const boost::filesystem::path & slice, const IceCompile::Deps & dep) :
+ IceCompile(slice, dep)
+{
+}
+
+void
+SliceCompile::Build(const boost::filesystem::path & in, const boost::filesystem::path & outpath) const
+{
+ std::vector<std::string> cppArgs;
+ Slice::PreprocessorPtr icecpp = Slice::Preprocessor::create("slice2project2", in.string(), cppArgs);
+ FILE * cppHandle = icecpp->preprocess(false);
+
+ if (cppHandle == NULL) {
+ throw std::runtime_error("preprocess failed");
+ }
+
+ Slice::UnitPtr u = Slice::Unit::createUnit(false, false, false, false);
+ ScopeObject uDestroy(boost::bind(&Slice::Unit::destroy, u.get()));
+
+ int parseStatus = u->parse(in.string(), cppHandle, false);
+
+ if (!icecpp->close()) {
+ throw std::runtime_error("preprocess close failed");
+ }
+
+ if (parseStatus == EXIT_FAILURE) {
+ throw std::runtime_error("unit parse failed");
+ }
+
+ FILE * out = fopen(outpath.string().c_str(), "w");
+ if (!out) {
+ throw std::runtime_error("failed to open target");
+ }
+
+ fprintf(out, "#include <%s>\n", (in.filename().replace_extension(".h")).string().c_str());
+ Headers(out);
+ fprintf(out, "\n");
+ Body(out, u);
+
+ if (fclose(out)) {
+ throw std::runtime_error("failed to close target");
+ }
+}
+
+void
+SliceCompile::Headers(FILE *) const
+{
+}
+
+boost::filesystem::path
+SliceCompile::InputPath() const
+{
+ return slice;
+}
+
diff --git a/project2/ice/sliceCompile.h b/project2/ice/sliceCompile.h
new file mode 100644
index 0000000..5f11c88
--- /dev/null
+++ b/project2/ice/sliceCompile.h
@@ -0,0 +1,21 @@
+#ifndef SLICECOMPILE_H
+#define SLICECOMPILE_H
+
+#include "iceCompile.h"
+#include <string>
+#include <Slice/Parser.h>
+#include <Slice/Preprocessor.h>
+
+class SliceCompile : public IceCompile {
+ public:
+ SliceCompile(const boost::filesystem::path & slice, const IceCompile::Deps & dep);
+
+ void Build(const boost::filesystem::path & in, const boost::filesystem::path & out) const;
+ virtual void Headers(FILE *) const;
+ virtual void Body(FILE *, Slice::UnitPtr) const = 0;
+
+ boost::filesystem::path InputPath() const;
+};
+
+#endif
+