[chronojump] Add rdotnet 1.5.0
- From: Andoni Morales Alastruey <amorales src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] Add rdotnet 1.5.0
- Date: Sun, 17 Feb 2013 21:13:42 +0000 (UTC)
commit 5b4f91c14b00361f0df26aaef613ac528a1904ac
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Sun Feb 17 22:10:37 2013 +0100
Add rdotnet 1.5.0
Makefile.am | 2 +-
configure.ac | 1 +
rdotnet/Makefile | 465 ++++++++++++++++
rdotnet/Makefile.am | 13 +
rdotnet/Makefile.in | 465 ++++++++++++++++
rdotnet/R.NET/BuiltinFunction.cs | 34 ++
rdotnet/R.NET/CharacterMatrix.cs | 99 ++++
rdotnet/R.NET/CharacterVector.cs | 90 +++
rdotnet/R.NET/Closure.cs | 74 +++
rdotnet/R.NET/ComplexMatrix.cs | 100 ++++
rdotnet/R.NET/ComplexVector.cs | 91 +++
rdotnet/R.NET/DataFrame.cs | 204 +++++++
rdotnet/R.NET/DataFrameRow.cs | 103 ++++
rdotnet/R.NET/Devices/CharacterDeviceAdapter.cs | 256 +++++++++
rdotnet/R.NET/Devices/ConsoleDevice.cs | 141 +++++
rdotnet/R.NET/Devices/ICharacterDevice.cs | 142 +++++
rdotnet/R.NET/Devices/NullCharacterDevice.cs | 84 +++
rdotnet/R.NET/Dynamic/DataFrameDynamicMeta.cs | 42 ++
rdotnet/R.NET/Dynamic/ListDynamicMeta.cs | 42 ++
.../R.NET/Dynamic/SymbolicExpressionDynamicMeta.cs | 41 ++
rdotnet/R.NET/DynamicVector.cs | 215 +++++++
rdotnet/R.NET/Environment.cs | 90 +++
rdotnet/R.NET/Expression.cs | 62 ++
rdotnet/R.NET/ExpressionVector.cs | 56 ++
rdotnet/R.NET/Function.cs | 26 +
rdotnet/R.NET/GenericVector.cs | 97 ++++
rdotnet/R.NET/IntegerMatrix.cs | 97 ++++
rdotnet/R.NET/IntegerVector.cs | 131 +++++
rdotnet/R.NET/InternalString.cs | 48 ++
rdotnet/R.NET/Internals/BusyType.cs | 18 +
rdotnet/R.NET/Internals/ConsoleOutputType.cs | 13 +
rdotnet/R.NET/Internals/Delegates.cs | 136 +++++
rdotnet/R.NET/Internals/OutputMode.cs | 31 +
rdotnet/R.NET/Internals/ParseStatus.cs | 46 ++
rdotnet/R.NET/Internals/SEXPREC.cs | 137 +++++
rdotnet/R.NET/Internals/SEXPREC_HEADER.cs | 14 +
rdotnet/R.NET/Internals/SaveActions.cs | 54 ++
rdotnet/R.NET/Internals/SymbolicExpressionType.cs | 188 +++++++
rdotnet/R.NET/Internals/Unix/Delegates.cs | 57 ++
rdotnet/R.NET/Internals/Unix/RStart.cs | 41 ++
rdotnet/R.NET/Internals/VECTOR_SEXPREC.cs | 60 ++
rdotnet/R.NET/Internals/Windows/Delegates.cs | 27 +
rdotnet/R.NET/Internals/Windows/RStart.cs | 37 ++
rdotnet/R.NET/Internals/Windows/UiMode.cs | 9 +
rdotnet/R.NET/Internals/YesNoCancel.cs | 23 +
rdotnet/R.NET/Internals/sxpinfo.cs | 60 ++
rdotnet/R.NET/Language.cs | 38 ++
rdotnet/R.NET/LogicalMatrix.cs | 96 ++++
rdotnet/R.NET/LogicalVector.cs | 91 +++
rdotnet/R.NET/Matrix.cs | 280 ++++++++++
rdotnet/R.NET/NumericMatrix.cs | 105 ++++
rdotnet/R.NET/NumericVector.cs | 133 +++++
rdotnet/R.NET/Pairlist.cs | 51 ++
rdotnet/R.NET/ParseException.cs | 70 +++
rdotnet/R.NET/Properties/AssemblyInfo.cs | 39 ++
rdotnet/R.NET/ProtectedPointer.cs | 43 ++
rdotnet/R.NET/RDotNet.csproj | 137 +++++
rdotnet/R.NET/REngine.cs | 529 ++++++++++++++++++
rdotnet/R.NET/REngineExtension.cs | 474 ++++++++++++++++
rdotnet/R.NET/RawMatrix.cs | 94 ++++
rdotnet/R.NET/RawVector.cs | 128 +++++
rdotnet/R.NET/SpecialFunction.cs | 34 ++
rdotnet/R.NET/StartupParameter.cs | 298 ++++++++++
rdotnet/R.NET/Symbol.cs | 76 +++
rdotnet/R.NET/SymbolicExpression.cs | 239 ++++++++
rdotnet/R.NET/SymbolicExpressionExtension.cs | 586 ++++++++++++++++++++
rdotnet/R.NET/Utility.cs | 29 +
rdotnet/R.NET/Vector.cs | 206 +++++++
rdotnet/RDotNet.NativeLibrary/NativeUtility.cs | 50 ++
.../Properties/AssemblyInfo.cs | 39 ++
.../RDotNet.NativeLibrary.csproj | 66 +++
rdotnet/RDotNet.NativeLibrary/UnmanagedDll.cs | 207 +++++++
rdotnet/RecycleBin.snk.pub | Bin 0 -> 288 bytes
src/Makefile.am | 5 +-
74 files changed, 8401 insertions(+), 4 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index fb3c534..c576747 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,7 +3,7 @@ EXTRA_DIST = m4 expansions.m4
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = chronopic-firmware \
- encoder libcesarplayer CesarPlayer src po manual
+ encoder libcesarplayer CesarPlayer rdotnet src po manual
if OSTYPE_LINUX
SUBDIRS += chronopic-tests chronojump_server
diff --git a/configure.ac b/configure.ac
index 9c942c0..f2fc7ac 100644
--- a/configure.ac
+++ b/configure.ac
@@ -130,6 +130,7 @@ CesarPlayer/Makefile
CesarPlayer/AssemblyInfo.cs
CesarPlayer/CesarPlayer.dll.config
win32/chronojump_innosetup.iss
+rdotnet/Makefile
])
AC_OUTPUT
diff --git a/rdotnet/Makefile b/rdotnet/Makefile
new file mode 100644
index 0000000..1148772
--- /dev/null
+++ b/rdotnet/Makefile
@@ -0,0 +1,465 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# rdotnet/Makefile. Generated from Makefile.in by configure.
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+
+
+pkgdatadir = $(datadir)/chronojump
+pkgincludedir = $(includedir)/chronojump
+pkglibdir = $(libdir)/chronojump
+pkglibexecdir = $(libexecdir)/chronojump
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = x86_64-unknown-linux-gnu
+host_triplet = x86_64-unknown-linux-gnu
+subdir = rdotnet
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/shamrock/expansions.m4 \
+ $(top_srcdir)/m4/shamrock/mono.m4 \
+ $(top_srcdir)/m4/shamrock/programs.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(chronojump_pkglibdir)"
+SCRIPTS = $(chronojump_pkglib_SCRIPTS)
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = ${SHELL} /home/andoni/git/chronojump/missing --run aclocal-1.11
+ACLOCAL_AMFLAGS = -I m4/shamrock -I m4/shave ${ACLOCAL_FLAGS}
+AMTAR = $${TAR-tar}
+AR = ar
+AUTOCONF = ${SHELL} /home/andoni/git/chronojump/missing --run autoconf
+AUTOHEADER = ${SHELL} /home/andoni/git/chronojump/missing --run autoheader
+AUTOMAKE = ${SHELL} /home/andoni/git/chronojump/missing --run automake-1.11
+AWK = gawk
+CC = gcc
+CCDEPMODE = depmode=gcc3
+CESARPLAYER_CFLAGS = -pthread -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include
-I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0
-I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
-I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/gstreamer-0.10
-I/usr/include/libxml2
+CESARPLAYER_LIBS = -pthread -lgtk-x11-2.0 -latk-1.0 -lpangoft2-1.0 -lfreetype -lfontconfig -lgdk-x11-2.0
-lpangocairo-1.0 -lgdk_pixbuf-2.0 -lpango-1.0 -lcairo -lgio-2.0 -lgstaudio-0.10 -lgstvideo-0.10
-lgstpbutils-0.10 -lgstinterfaces-0.10 -lgstapp-0.10 -lgstbase-0.10 -lgsttag-0.10 -lgstreamer-0.10
-lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lxml2 -lglib-2.0
+CFLAGS = -g -O2
+CPP = gcc -E
+CPPFLAGS =
+CYGPATH_W = echo
+DEFS = -DPACKAGE_NAME=\"chronojump\" -DPACKAGE_TARNAME=\"chronojump\" -DPACKAGE_VERSION=\"1.3.3\"
-DPACKAGE_STRING=\"chronojump\ 1.3.3\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"chronojump\"
-DVERSION=\"1.3.3\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1
-DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1
-DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DOSTYPE_LINUX=1
+DEPDIR = .deps
+DLLTOOL = false
+DSYMUTIL =
+DUMPBIN =
+ECHO_C =
+ECHO_N = -n
+ECHO_T =
+EGREP = /bin/grep -E
+EXEEXT =
+FGREP = /bin/grep -F
+GLADE_SHARP_20_CFLAGS = -I:/usr/lib/pkgconfig/../../share/gapi-2.0/glade-api.xml
-I:/usr/lib/pkgconfig/../../share/gapi-2.0/pango-api.xml
-I:/usr/lib/pkgconfig/../../share/gapi-2.0/atk-api.xml -I:/usr/lib/pkgconfig/../../share/gapi-2.0/gdk-api.xml
-I:/usr/lib/pkgconfig/../../share/gapi-2.0/gtk-api.xml
-I:/usr/lib/pkgconfig/../../share/gapi-2.0/glib-api.xml
+GLADE_SHARP_20_LIBS = -r:/usr/lib/pkgconfig/../../lib/cli/glade-sharp-2.0/glade-sharp.dll
-r:/usr/lib/pkgconfig/../../lib/cli/pango-sharp-2.0/pango-sharp.dll
-r:/usr/lib/pkgconfig/../../lib/cli/atk-sharp-2.0/atk-sharp.dll
-r:/usr/lib/pkgconfig/../../lib/cli/gdk-sharp-2.0/gdk-sharp.dll
-r:/usr/lib/pkgconfig/../../lib/cli/gtk-sharp-2.0/gtk-sharp.dll
-r:/usr/lib/pkgconfig/../../lib/cli/glib-sharp-2.0/glib-sharp.dll
+GLIB_SHARP_20_CFLAGS = -I:/usr/lib/pkgconfig/../../share/gapi-2.0/glib-api.xml
+GLIB_SHARP_20_LIBS = -r:/usr/lib/pkgconfig/../../lib/cli/glib-sharp-2.0/glib-sharp.dll
+GREP = /bin/grep
+GTK_SHARP_20_CFLAGS = -I:/usr/lib/pkgconfig/../../share/gapi-2.0/pango-api.xml
-I:/usr/lib/pkgconfig/../../share/gapi-2.0/atk-api.xml -I:/usr/lib/pkgconfig/../../share/gapi-2.0/gdk-api.xml
-I:/usr/lib/pkgconfig/../../share/gapi-2.0/gtk-api.xml
-I:/usr/lib/pkgconfig/../../share/gapi-2.0/glib-api.xml
+GTK_SHARP_20_LIBS = -r:/usr/lib/pkgconfig/../../lib/cli/pango-sharp-2.0/pango-sharp.dll
-r:/usr/lib/pkgconfig/../../lib/cli/atk-sharp-2.0/atk-sharp.dll
-r:/usr/lib/pkgconfig/../../lib/cli/gdk-sharp-2.0/gdk-sharp.dll
-r:/usr/lib/pkgconfig/../../lib/cli/gtk-sharp-2.0/gtk-sharp.dll
-r:/usr/lib/pkgconfig/../../lib/cli/glib-sharp-2.0/glib-sharp.dll
+INSTALL = /usr/bin/install -c
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_SCRIPT = ${INSTALL}
+INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
+LD = /usr/bin/ld -m elf_x86_64
+LDFLAGS =
+LIBOBJS =
+LIBS =
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LIPO =
+LN_S = ln -s
+LTLIBOBJS =
+MAINT =
+MAKEINFO = ${SHELL} /home/andoni/git/chronojump/missing --run makeinfo
+MANIFEST_TOOL = :
+MCS = /usr/bin/dmcs
+MKDIR_P = /bin/mkdir -p
+MONO = /usr/bin/mono
+MONO_MODULE_CFLAGS =
+MONO_MODULE_LIBS =
+MSGFMT = msgfmt
+NM = /usr/bin/nm -B
+NMEDIT =
+OBJDUMP = objdump
+OBJEXT = o
+OTOOL =
+OTOOL64 =
+PACKAGE = chronojump
+PACKAGE_BUGREPORT =
+PACKAGE_NAME = chronojump
+PACKAGE_STRING = chronojump 1.3.3
+PACKAGE_TARNAME = chronojump
+PACKAGE_URL =
+PACKAGE_VERSION = 1.3.3
+PATH_SEPARATOR = :
+PKG_CONFIG = /usr/bin/pkg-config
+PKG_CONFIG_LIBDIR =
+PKG_CONFIG_PATH =
+PYTHON = /usr/bin/python
+PYTHON_EXEC_PREFIX = ${exec_prefix}
+PYTHON_PLATFORM = linux2
+PYTHON_PREFIX = ${prefix}
+PYTHON_VERSION = 2.7
+RANLIB = ranlib
+SED = /bin/sed
+SET_MAKE =
+SHELL = /bin/bash
+STRIP = strip
+VERSION = 1.3.3
+abs_builddir = /home/andoni/git/chronojump/rdotnet
+abs_srcdir = /home/andoni/git/chronojump/rdotnet
+abs_top_builddir = /home/andoni/git/chronojump
+abs_top_srcdir = /home/andoni/git/chronojump
+ac_ct_AR = ar
+ac_ct_CC = gcc
+ac_ct_DUMPBIN =
+am__include = include
+am__leading_dot = .
+am__quote =
+am__tar = $${TAR-tar} chof - "$$tardir"
+am__untar = $${TAR-tar} xf -
+bindir = ${exec_prefix}/bin
+build = x86_64-unknown-linux-gnu
+build_alias =
+build_cpu = x86_64
+build_os = linux-gnu
+build_vendor = unknown
+builddir = .
+datadir = ${datarootdir}
+datarootdir = ${prefix}/share
+docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
+dvidir = ${docdir}
+exec_prefix = /usr/local
+expanded_bindir = /usr/local/bin
+expanded_datadir = /usr/local/share
+expanded_libdir = /usr/local/lib
+host = x86_64-unknown-linux-gnu
+host_alias =
+host_cpu = x86_64
+host_os = linux-gnu
+host_vendor = unknown
+htmldir = ${docdir}
+includedir = ${prefix}/include
+infodir = ${datarootdir}/info
+install_sh = ${SHELL} /home/andoni/git/chronojump/install-sh
+libdir = ${exec_prefix}/lib
+libexecdir = ${exec_prefix}/libexec
+localedir = ${datarootdir}/locale
+localstatedir = ${prefix}/var
+mandir = ${datarootdir}/man
+mkdir_p = /bin/mkdir -p
+oldincludedir = /usr/include
+pdfdir = ${docdir}
+pkgpyexecdir = ${pyexecdir}/chronojump
+pkgpythondir = ${pythondir}/chronojump
+prefix = /usr/local
+program_transform_name = s,x,x,
+psdir = ${docdir}
+pyexecdir = ${exec_prefix}/lib/python2.7/dist-packages
+pythondir = ${prefix}/lib/python2.7/dist-packages
+sbindir = ${exec_prefix}/sbin
+sharedstatedir = ${prefix}/com
+srcdir = .
+sysconfdir = ${prefix}/etc
+target_alias =
+top_build_prefix = ../
+top_builddir = ..
+top_srcdir = ..
+R_NET_BIN_FOLDER = R.NET/bin/Debug
+R_NET_ASSEMBLY = $(R_NET_BIN_FOLDER)/RDotNet.dll
+R_NET_NATIVE_ASSEMBLY = $(R_NET_BIN_FOLDER)/RDotNet.NativeLibrary.dll
+chronojump_pkglibdir = $(pkglibdir)
+chronojump_pkglib_SCRIPTS = $(R_NET_ASSEMBLY) $(R_NET_NATIVE_ASSEMBLY)
+CLEANFILES = $(R_NET_ASSEMBLY) $(R_NET_NATIVE_ASSEMBLY)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign rdotnet/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign rdotnet/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-chronojump_pkglibSCRIPTS: $(chronojump_pkglib_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(chronojump_pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(chronojump_pkglibdir)"
+ @list='$(chronojump_pkglib_SCRIPTS)'; test -n "$(chronojump_pkglibdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(chronojump_pkglibdir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(chronojump_pkglibdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-chronojump_pkglibSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(chronojump_pkglib_SCRIPTS)'; test -n "$(chronojump_pkglibdir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(chronojump_pkglibdir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(SCRIPTS)
+installdirs:
+ for dir in "$(DESTDIR)$(chronojump_pkglibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-chronojump_pkglibSCRIPTS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-chronojump_pkglibSCRIPTS
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-chronojump_pkglibSCRIPTS install-data install-data-am \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am uninstall uninstall-am \
+ uninstall-chronojump_pkglibSCRIPTS
+
+
+$(R_NET_ASSEMBLY) $(R_NET_NATIVE_ASSEMBLY):
+ xbuild R.NET/RDotNet.csproj
+
+all: $(R_NET_ASSEMBLY) $(R_NET_NATIVE_ASSEMBLY)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/rdotnet/Makefile.am b/rdotnet/Makefile.am
new file mode 100644
index 0000000..46b7abf
--- /dev/null
+++ b/rdotnet/Makefile.am
@@ -0,0 +1,13 @@
+R_NET_BIN_FOLDER = R.NET/bin/Debug
+R_NET_ASSEMBLY = $(R_NET_BIN_FOLDER)/RDotNet.dll
+R_NET_NATIVE_ASSEMBLY = $(R_NET_BIN_FOLDER)/RDotNet.NativeLibrary.dll
+
+$(R_NET_ASSEMBLY) $(R_NET_NATIVE_ASSEMBLY):
+ xbuild R.NET/RDotNet.csproj
+
+all: $(R_NET_ASSEMBLY) $(R_NET_NATIVE_ASSEMBLY)
+
+chronojump_pkglibdir = $(pkglibdir)
+chronojump_pkglib_SCRIPTS = $(R_NET_ASSEMBLY) $(R_NET_NATIVE_ASSEMBLY)
+
+CLEANFILES = $(R_NET_ASSEMBLY) $(R_NET_NATIVE_ASSEMBLY)
diff --git a/rdotnet/Makefile.in b/rdotnet/Makefile.in
new file mode 100644
index 0000000..fbfe429
--- /dev/null
+++ b/rdotnet/Makefile.in
@@ -0,0 +1,465 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = rdotnet
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/shamrock/expansions.m4 \
+ $(top_srcdir)/m4/shamrock/mono.m4 \
+ $(top_srcdir)/m4/shamrock/programs.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(chronojump_pkglibdir)"
+SCRIPTS = $(chronojump_pkglib_SCRIPTS)
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CESARPLAYER_CFLAGS = @CESARPLAYER_CFLAGS@
+CESARPLAYER_LIBS = @CESARPLAYER_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
+GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
+GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
+GLIB_SHARP_20_LIBS = @GLIB_SHARP_20_LIBS@
+GREP = @GREP@
+GTK_SHARP_20_CFLAGS = @GTK_SHARP_20_CFLAGS@
+GTK_SHARP_20_LIBS = @GTK_SHARP_20_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MCS = @MCS@
+MKDIR_P = @MKDIR_P@
+MONO = @MONO@
+MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
+MONO_MODULE_LIBS = @MONO_MODULE_LIBS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+expanded_bindir = @expanded_bindir@
+expanded_datadir = @expanded_datadir@
+expanded_libdir = @expanded_libdir@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+R_NET_BIN_FOLDER = R.NET/bin/Debug
+R_NET_ASSEMBLY = $(R_NET_BIN_FOLDER)/RDotNet.dll
+R_NET_NATIVE_ASSEMBLY = $(R_NET_BIN_FOLDER)/RDotNet.NativeLibrary.dll
+chronojump_pkglibdir = $(pkglibdir)
+chronojump_pkglib_SCRIPTS = $(R_NET_ASSEMBLY) $(R_NET_NATIVE_ASSEMBLY)
+CLEANFILES = $(R_NET_ASSEMBLY) $(R_NET_NATIVE_ASSEMBLY)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign rdotnet/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign rdotnet/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-chronojump_pkglibSCRIPTS: $(chronojump_pkglib_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(chronojump_pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(chronojump_pkglibdir)"
+ @list='$(chronojump_pkglib_SCRIPTS)'; test -n "$(chronojump_pkglibdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(chronojump_pkglibdir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(chronojump_pkglibdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-chronojump_pkglibSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(chronojump_pkglib_SCRIPTS)'; test -n "$(chronojump_pkglibdir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(chronojump_pkglibdir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(SCRIPTS)
+installdirs:
+ for dir in "$(DESTDIR)$(chronojump_pkglibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-chronojump_pkglibSCRIPTS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-chronojump_pkglibSCRIPTS
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-chronojump_pkglibSCRIPTS install-data install-data-am \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am uninstall uninstall-am \
+ uninstall-chronojump_pkglibSCRIPTS
+
+
+$(R_NET_ASSEMBLY) $(R_NET_NATIVE_ASSEMBLY):
+ xbuild R.NET/RDotNet.csproj
+
+all: $(R_NET_ASSEMBLY) $(R_NET_NATIVE_ASSEMBLY)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/rdotnet/R.NET/BuiltinFunction.cs b/rdotnet/R.NET/BuiltinFunction.cs
new file mode 100644
index 0000000..edcca4b
--- /dev/null
+++ b/rdotnet/R.NET/BuiltinFunction.cs
@@ -0,0 +1,34 @@
+ïusing System;
+using System.Linq;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A built-in function.
+ /// </summary>
+ public class BuiltinFunction : Function
+ {
+ /// <summary>
+ /// Creates a built-in function proxy.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="pointer">The pointer.</param>
+ protected internal BuiltinFunction(REngine engine, IntPtr pointer)
+ : base(engine, pointer)
+ {}
+
+ public override SymbolicExpression Invoke(SymbolicExpression[] args)
+ {
+ IntPtr argument = Engine.NilValue.DangerousGetHandle();
+ foreach (SymbolicExpression arg in args.Reverse())
+ {
+ argument = Engine.GetFunction<Rf_cons>("Rf_cons")(arg.DangerousGetHandle(),
argument);
+ }
+ IntPtr call = Engine.GetFunction<Rf_lcons>("Rf_lcons")(handle, argument);
+
+ IntPtr result = Engine.GetFunction<Rf_eval>("Rf_eval")(call,
Engine.GlobalEnvironment.DangerousGetHandle());
+ return new SymbolicExpression(Engine, result);
+ }
+ }
+}
diff --git a/rdotnet/R.NET/CharacterMatrix.cs b/rdotnet/R.NET/CharacterMatrix.cs
new file mode 100644
index 0000000..f27c55c
--- /dev/null
+++ b/rdotnet/R.NET/CharacterMatrix.cs
@@ -0,0 +1,99 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A matrix of strings.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class CharacterMatrix : Matrix<string>
+ {
+ /// <summary>
+ /// Creates a new empty CharacterMatrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="rowCount">The row size.</param>
+ /// <param name="columnCount">The column size.</param>
+ /// <seealso cref="REngineExtension.CreateCharacterMatrix(REngine, int, int)"/>
+ public CharacterMatrix(REngine engine, int rowCount, int columnCount)
+ : base(engine, SymbolicExpressionType.CharacterVector, rowCount, columnCount)
+ {}
+
+ /// <summary>
+ /// Creates a new CharacterMatrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="matrix">The values.</param>
+ /// <seealso cref="REngineExtension.CreateCharacterMatrix(REngine, string[,])"/>
+ public CharacterMatrix(REngine engine, string[,] matrix)
+ : base(engine, SymbolicExpressionType.CharacterVector, matrix)
+ {}
+
+ /// <summary>
+ /// Creates a new instance for a string matrix.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a string matrix.</param>
+ protected internal CharacterMatrix(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="rowIndex">The zero-based rowIndex index of the element to get or set.</param>
+ /// <param name="columnIndex">The zero-based columnIndex index of the element to get or
set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override string this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex < 0 || RowCount <= rowIndex)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex < 0 || ColumnCount <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(rowIndex, columnIndex);
+ IntPtr pointer = Marshal.ReadIntPtr(DataPointer, offset);
+ return new InternalString(Engine, pointer);
+ }
+ }
+ set
+ {
+ if (rowIndex < 0 || RowCount <= rowIndex)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex < 0 || ColumnCount <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(rowIndex, columnIndex);
+ SymbolicExpression s = value == null ? Engine.NilValue : new
InternalString(Engine, value);
+ using (new ProtectedPointer(s))
+ {
+ Marshal.WriteIntPtr(DataPointer, offset,
s.DangerousGetHandle());
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of a pointer in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get { return Marshal.SizeOf(typeof(IntPtr)); }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/CharacterVector.cs b/rdotnet/R.NET/CharacterVector.cs
new file mode 100644
index 0000000..1e07f6c
--- /dev/null
+++ b/rdotnet/R.NET/CharacterVector.cs
@@ -0,0 +1,90 @@
+ïusing System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A collection of strings.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class CharacterVector : Vector<string>
+ {
+ /// <summary>
+ /// Creates a new empty CharacterVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="length">The length.</param>
+ /// <seealso cref="REngineExtension.CreateCharacterVector(REngine, int)"/>
+ public CharacterVector(REngine engine, int length)
+ : base(engine, SymbolicExpressionType.CharacterVector, length)
+ {}
+
+ /// <summary>
+ /// Creates a new CharacterVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="vector">The values.</param>
+ /// <seealso cref="REngineExtension.CreateCharacterVector(REngine, IEnumerable{string})"/>
+ public CharacterVector(REngine engine, IEnumerable<string> vector)
+ : base(engine, SymbolicExpressionType.CharacterVector, vector)
+ {}
+
+ /// <summary>
+ /// Creates a new instance for a string vector.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a string vector.</param>
+ protected internal CharacterVector(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index of the element to get or set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override string this[int index]
+ {
+ get
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(index);
+ IntPtr pointer = Marshal.ReadIntPtr(DataPointer, offset);
+ return new InternalString(Engine, pointer);
+ }
+ }
+ set
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(index);
+ SymbolicExpression s = value == null ? Engine.NilValue : new
InternalString(Engine, value);
+ using (new ProtectedPointer(s))
+ {
+ Marshal.WriteIntPtr(DataPointer, offset,
s.DangerousGetHandle());
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of a pointer in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get { return Marshal.SizeOf(typeof(IntPtr)); }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Closure.cs b/rdotnet/R.NET/Closure.cs
new file mode 100644
index 0000000..b31c51d
--- /dev/null
+++ b/rdotnet/R.NET/Closure.cs
@@ -0,0 +1,74 @@
+ïusing System;
+using System.Linq;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A closure.
+ /// </summary>
+ public class Closure : Function
+ {
+ /// <summary>
+ /// Creates a closure object.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="pointer">The pointer.</param>
+ protected internal Closure(REngine engine, IntPtr pointer)
+ : base(engine, pointer)
+ {}
+
+ /// <summary>
+ /// Gets the arguments list.
+ /// </summary>
+ public Pairlist Arguments
+ {
+ get
+ {
+ SEXPREC sexp = GetInternalStructure();
+ return new Pairlist(Engine, sexp.closxp.formals);
+ }
+ }
+
+ /// <summary>
+ /// Gets the body.
+ /// </summary>
+ public Language Body
+ {
+ get
+ {
+ SEXPREC sexp = GetInternalStructure();
+ return new Language(Engine, sexp.closxp.body);
+ }
+ }
+
+ /// <summary>
+ /// Gets the environment.
+ /// </summary>
+ public REnvironment Environment
+ {
+ get
+ {
+ SEXPREC sexp = GetInternalStructure();
+ return new REnvironment(Engine, sexp.closxp.env);
+ }
+ }
+
+ public override SymbolicExpression Invoke(SymbolicExpression[] args)
+ {
+ int count = Arguments.Count;
+ if (args.Length != count)
+ {
+ throw new ArgumentException();
+ }
+
+ var arguments = new GenericVector(Engine, args);
+ var names = new CharacterVector(Engine, Arguments.Select(arg =>
arg.PrintName).ToArray());
+ arguments.SetAttribute(Engine.GetPredefinedSymbol("R_NamesSymbol"), names);
+
+ IntPtr newEnvironment =
Engine.GetFunction<Rf_allocSExp>("Rf_allocSExp")(SymbolicExpressionType.Environment);
+ IntPtr result =
Engine.GetFunction<Rf_applyClosure>("Rf_applyClosure")(Body.DangerousGetHandle(), handle,
arguments.ToPairlist().DangerousGetHandle(), Environment.DangerousGetHandle(), newEnvironment);
+ return new SymbolicExpression(Engine, result);
+ }
+ }
+}
diff --git a/rdotnet/R.NET/ComplexMatrix.cs b/rdotnet/R.NET/ComplexMatrix.cs
new file mode 100644
index 0000000..0bc46d4
--- /dev/null
+++ b/rdotnet/R.NET/ComplexMatrix.cs
@@ -0,0 +1,100 @@
+ïusing System;
+using System.Numerics;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A matrix of complex numbers.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class ComplexMatrix : Matrix<Complex>
+ {
+ /// <summary>
+ /// Creates a new empty ComplexMatrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="rowCount">The row size.</param>
+ /// <param name="columnCount">The column size.</param>
+ /// <seealso cref="REngineExtension.CreateComplexMatrix(REngine, int, int)"/>
+ public ComplexMatrix(REngine engine, int rowCount, int columnCount)
+ : base(engine, SymbolicExpressionType.ComplexVector, rowCount, columnCount)
+ {}
+
+ /// <summary>
+ /// Creates a new ComplexMatrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="matrix">The values.</param>
+ /// <seealso cref="REngineExtension.CreateComplexMatrix(REngine, Complex[,])"/>
+ public ComplexMatrix(REngine engine, Complex[,] matrix)
+ : base(engine, SymbolicExpressionType.CharacterVector, matrix)
+ {}
+
+ /// <summary>
+ /// Creates a new instance for a complex number matrix.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a complex number matrix.</param>
+ protected internal ComplexMatrix(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="rowIndex">The zero-based rowIndex index of the element to get or set.</param>
+ /// <param name="columnIndex">The zero-based columnIndex index of the element to get or
set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override Complex this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex < 0 || RowCount <= rowIndex)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex < 0 || ColumnCount <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ using (new ProtectedPointer(this))
+ {
+ var data = new double[2];
+ int offset = GetOffset(rowIndex, columnIndex);
+ IntPtr pointer = IntPtr.Add(DataPointer, offset);
+ Marshal.Copy(pointer, data, 0, data.Length);
+ return new Complex(data[0], data[1]);
+ }
+ }
+ set
+ {
+ if (rowIndex < 0 || RowCount <= rowIndex)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex < 0 || ColumnCount <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ using (new ProtectedPointer(this))
+ {
+ var data = new[] { value.Real, value.Imaginary };
+ int offset = GetOffset(rowIndex, columnIndex);
+ IntPtr pointer = IntPtr.Add(DataPointer, offset);
+ Marshal.Copy(data, 0, pointer, data.Length);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of a complex number in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get { return Marshal.SizeOf(typeof(Complex)); }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/ComplexVector.cs b/rdotnet/R.NET/ComplexVector.cs
new file mode 100644
index 0000000..ba5db93
--- /dev/null
+++ b/rdotnet/R.NET/ComplexVector.cs
@@ -0,0 +1,91 @@
+ïusing System;
+using System.Collections.Generic;
+using System.Numerics;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A collection of complex numbers.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class ComplexVector : Vector<Complex>
+ {
+ /// <summary>
+ /// Creates a new empty ComplexVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="length">The length.</param>
+ /// <seealso cref="REngineExtension.CreateComplexVector(REngine, int)"/>
+ public ComplexVector(REngine engine, int length)
+ : base(engine, SymbolicExpressionType.ComplexVector, length)
+ {}
+
+ /// <summary>
+ /// Creates a new ComplexVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="vector">The values.</param>
+ /// <seealso cref="REngineExtension.CreateComplexVector(REngine,
System.Collections.Generic.IEnumerable{System.Numerics.Complex})"/>
+ public ComplexVector(REngine engine, IEnumerable<Complex> vector)
+ : base(engine, SymbolicExpressionType.ComplexVector, vector)
+ {}
+
+ /// <summary>
+ /// Creates a new instance for a complex number vector.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a complex number vector.</param>
+ protected internal ComplexVector(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index of the element to get or set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override Complex this[int index]
+ {
+ get
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ var data = new double[2];
+ int offset = GetOffset(index);
+ IntPtr pointer = IntPtr.Add(DataPointer, offset);
+ Marshal.Copy(pointer, data, 0, data.Length);
+ return new Complex(data[0], data[1]);
+ }
+ }
+ set
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ var data = new[] { value.Real, value.Imaginary };
+ int offset = GetOffset(index);
+ IntPtr pointer = IntPtr.Add(DataPointer, offset);
+ Marshal.Copy(data, 0, pointer, data.Length);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of a complex number in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get { return Marshal.SizeOf(typeof(Complex)); }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/DataFrame.cs b/rdotnet/R.NET/DataFrame.cs
new file mode 100644
index 0000000..e267951
--- /dev/null
+++ b/rdotnet/R.NET/DataFrame.cs
@@ -0,0 +1,204 @@
+ïusing System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Dynamic;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A data frame.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class DataFrame : Vector<DynamicVector>
+ {
+ private const string RRowNamesSymbolName = "R_RowNamesSymbol";
+
+ /// <summary>
+ /// Creates a new instance.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a data frame.</param>
+ protected internal DataFrame(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the column at the specified index as a vector.
+ /// </summary>
+ /// <param name="columnIndex">The zero-based index of the column to get or set.</param>
+ /// <returns>The column at the specified index.</returns>
+ public override DynamicVector this[int columnIndex]
+ {
+ get
+ {
+ if (columnIndex < 0 || Length <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(columnIndex);
+ IntPtr pointer = Marshal.ReadIntPtr(DataPointer, offset);
+ return new DynamicVector(Engine, pointer);
+ }
+ }
+ set
+ {
+ if (columnIndex < 0 || Length <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(columnIndex);
+ Marshal.WriteIntPtr(DataPointer, offset, (value ??
Engine.NilValue).DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the element at the specified indexes.
+ /// </summary>
+ /// <param name="rowIndex">The row index.</param>
+ /// <param name="columnIndex">The column index.</param>
+ /// <returns>The element.</returns>
+ public object this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ DynamicVector column = this[columnIndex];
+ return column[rowIndex];
+ }
+ set
+ {
+ DynamicVector column = this[columnIndex];
+ column[rowIndex] = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the element at the specified index and name.
+ /// </summary>
+ /// <param name="rowIndex">The row index.</param>
+ /// <param name="columnName">The column name.</param>
+ /// <returns>The element.</returns>
+ public object this[int rowIndex, string columnName]
+ {
+ get
+ {
+ DynamicVector column = this[columnName];
+ return column[rowIndex];
+ }
+ set
+ {
+ DynamicVector column = this[columnName];
+ column[rowIndex] = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the element at the specified names.
+ /// </summary>
+ /// <param name="rowName">The row name.</param>
+ /// <param name="columnName">The column name.</param>
+ /// <returns>The element.</returns>
+ public object this[string rowName, string columnName]
+ {
+ get
+ {
+ DynamicVector column = this[columnName];
+ return column[rowName];
+ }
+ set
+ {
+ DynamicVector column = this[columnName];
+ column[rowName] = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of data sets.
+ /// </summary>
+ public int RowCount
+ {
+ get { return ColumnCount == 0 ? 0 : this[0].Length; }
+ }
+
+ /// <summary>
+ /// Gets the number of kinds of data.
+ /// </summary>
+ public int ColumnCount
+ {
+ get { return Length; }
+ }
+
+ /// <summary>
+ /// Gets the names of rows.
+ /// </summary>
+ public string[] RowNames
+ {
+ get
+ {
+ SymbolicExpression rowNamesSymbol =
Engine.GetPredefinedSymbol(RRowNamesSymbolName);
+ SymbolicExpression rowNames = GetAttribute(rowNamesSymbol);
+ if (rowNames == null)
+ {
+ return null;
+ }
+ CharacterVector rowNamesVector = rowNames.AsCharacter();
+ if (rowNamesVector == null)
+ {
+ return null;
+ }
+
+ int length = rowNamesVector.Length;
+ var result = new string[length];
+ rowNamesVector.CopyTo(result, length);
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Gets the names of columns.
+ /// </summary>
+ public string[] ColumnNames
+ {
+ get { return Names; }
+ }
+
+ protected override int DataSize
+ {
+ get { return Marshal.SizeOf(typeof(IntPtr)); }
+ }
+
+ /// <summary>
+ /// Gets the row at the specified index.
+ /// </summary>
+ /// <param name="rowIndex">The index.</param>
+ /// <returns>The row.</returns>
+ public DataFrameRow GetRow(int rowIndex)
+ {
+ return new DataFrameRow(this, rowIndex);
+ }
+
+ /// <summary>
+ /// Enumerates all the rows in the data frame.
+ /// </summary>
+ /// <returns>The collection of the rows.</returns>
+ public IEnumerable<DataFrameRow> GetRows()
+ {
+ int rowCount = RowCount;
+ for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
+ {
+ yield return GetRow(rowIndex);
+ }
+ }
+
+ public override DynamicMetaObject GetMetaObject(System.Linq.Expressions.Expression parameter)
+ {
+ return new DataFrameDynamicMeta(parameter, this);
+ }
+ }
+}
diff --git a/rdotnet/R.NET/DataFrameRow.cs b/rdotnet/R.NET/DataFrameRow.cs
new file mode 100644
index 0000000..a47df59
--- /dev/null
+++ b/rdotnet/R.NET/DataFrameRow.cs
@@ -0,0 +1,103 @@
+ïusing System;
+using System.Collections.Generic;
+using System.Dynamic;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A data frame row.
+ /// </summary>
+ public class DataFrameRow : DynamicObject
+ {
+ private DataFrame frame;
+ private int rowIndex;
+
+ public DataFrameRow(DataFrame frame, int rowIndex)
+ {
+ this.frame = frame;
+ this.rowIndex = rowIndex;
+ }
+
+ /// <summary>
+ /// Gets and sets the value at the specified column.
+ /// </summary>
+ /// <param name="index">The column index.</param>
+ /// <returns>The value.</returns>
+ public object this[int index]
+ {
+ get
+ {
+ DynamicVector column = DataFrame[index];
+ return column[RowIndex];
+ }
+ set
+ {
+ DynamicVector column = DataFrame[index];
+ column[RowIndex] = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the value at the specified column.
+ /// </summary>
+ /// <param name="name">The column name.</param>
+ /// <returns>The value.</returns>
+ public object this[string name]
+ {
+ get
+ {
+ DynamicVector column = DataFrame[name];
+ return column[RowIndex];
+ }
+ set
+ {
+ DynamicVector column = DataFrame[name];
+ column[RowIndex] = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the data frame containing this row.
+ /// </summary>
+ public DataFrame DataFrame
+ {
+ get { return this.frame; }
+ }
+
+ /// <summary>
+ /// Gets the index of this row.
+ /// </summary>
+ public int RowIndex
+ {
+ get { return this.rowIndex; }
+ }
+
+ public override IEnumerable<string> GetDynamicMemberNames()
+ {
+ return DataFrame.ColumnNames;
+ }
+
+ public override bool TryGetMember(GetMemberBinder binder, out object result)
+ {
+ string[] columnNames = DataFrame.ColumnNames;
+ if (columnNames == null || Array.IndexOf(columnNames, binder.Name) < 0)
+ {
+ result = null;
+ return false;
+ }
+ result = this[binder.Name];
+ return true;
+ }
+
+ public override bool TrySetMember(SetMemberBinder binder, object value)
+ {
+ string[] columnNames = DataFrame.ColumnNames;
+ if (columnNames == null || Array.IndexOf(columnNames, binder.Name) < 0)
+ {
+ return false;
+ }
+ this[binder.Name] = value;
+ return true;
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Devices/CharacterDeviceAdapter.cs b/rdotnet/R.NET/Devices/CharacterDeviceAdapter.cs
new file mode 100644
index 0000000..7183915
--- /dev/null
+++ b/rdotnet/R.NET/Devices/CharacterDeviceAdapter.cs
@@ -0,0 +1,256 @@
+ïusing System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using RDotNet.Internals;
+using RDotNet.Internals.Unix;
+using RDotNet.Internals.Windows;
+
+namespace RDotNet.Devices
+{
+ internal class CharacterDeviceAdapter : IDisposable
+ {
+ private readonly ICharacterDevice device;
+
+ private REngine engine;
+
+ /// <summary>
+ /// Creates an instance.
+ /// </summary>
+ /// <param name="device">The implementation.</param>
+ public CharacterDeviceAdapter(ICharacterDevice device)
+ {
+ if (device == null)
+ {
+ throw new ArgumentNullException("device");
+ }
+ this.device = device;
+ }
+
+ /// <summary>
+ /// Gets the implementation of <see cref="ICharacterDevice"/> interface.
+ /// </summary>
+ public ICharacterDevice Device
+ {
+ get { return this.device; }
+ }
+
+ private REngine Engine
+ {
+ get { return this.engine; }
+ }
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ GC.KeepAlive(this);
+ }
+
+ #endregion
+
+ internal void Install(REngine engine, StartupParameter parameter)
+ {
+ this.engine = engine;
+ switch (Environment.OSVersion.Platform)
+ {
+ case PlatformID.Win32NT:
+ SetupWindowsDevice(parameter);
+ break;
+ case PlatformID.MacOSX:
+ case PlatformID.Unix:
+ SetupUnixDevice();
+ break;
+ }
+ }
+
+ private void SetupWindowsDevice(StartupParameter parameter)
+ {
+ string rhome =
Marshal.PtrToStringAnsi(this.engine.GetFunction<getValue>("get_R_HOME")());
+ parameter.start.rhome = Marshal.StringToHGlobalAnsi(ConvertSeparator(rhome));
+ string home =
Marshal.PtrToStringAnsi(this.engine.GetFunction<getValue>("getRUser")());
+ parameter.start.home = Marshal.StringToHGlobalAnsi(ConvertSeparator(home));
+ parameter.start.CharacterMode = UiMode.LinkDll;
+ parameter.start.ReadConsole = ReadConsole;
+ parameter.start.WriteConsole = WriteConsole;
+ parameter.start.WriteConsoleEx = WriteConsoleEx;
+ parameter.start.CallBack = Callback;
+ parameter.start.ShowMessage = ShowMessage;
+ parameter.start.YesNoCancel = Ask;
+ parameter.start.Busy = Busy;
+ }
+
+ private void SetupUnixDevice()
+ {
+ IntPtr suicidePointer = this.engine.DangerousGetHandle("ptr_R_Suicide");
+ IntPtr newSuicide = Marshal.GetFunctionPointerForDelegate((ptr_R_Suicide)Suicide);
+ Marshal.WriteIntPtr(suicidePointer, newSuicide);
+ IntPtr showMessagePointer = this.engine.DangerousGetHandle("ptr_R_ShowMessage");
+ IntPtr newShowMessage =
Marshal.GetFunctionPointerForDelegate((ptr_R_ShowMessage)ShowMessage);
+ Marshal.WriteIntPtr(showMessagePointer, newShowMessage);
+ IntPtr readConsolePointer = this.engine.DangerousGetHandle("ptr_R_ReadConsole");
+ IntPtr newReadConsole =
Marshal.GetFunctionPointerForDelegate((ptr_R_ReadConsole)ReadConsole);
+ Marshal.WriteIntPtr(readConsolePointer, newReadConsole);
+ IntPtr writeConsolePointer = this.engine.DangerousGetHandle("ptr_R_WriteConsole");
+ IntPtr newWriteConsole =
Marshal.GetFunctionPointerForDelegate((ptr_R_WriteConsole)WriteConsole);
+ Marshal.WriteIntPtr(writeConsolePointer, newWriteConsole);
+ IntPtr writeConsoleExPointer = this.engine.DangerousGetHandle("ptr_R_WriteConsoleEx");
+ IntPtr newWriteConsoleEx =
Marshal.GetFunctionPointerForDelegate((ptr_R_WriteConsoleEx)WriteConsoleEx);
+ Marshal.WriteIntPtr(writeConsoleExPointer, newWriteConsoleEx);
+ IntPtr resetConsolePointer = this.engine.DangerousGetHandle("ptr_R_ResetConsole");
+ IntPtr newResetConsole =
Marshal.GetFunctionPointerForDelegate((ptr_R_ResetConsole)ResetConsole);
+ Marshal.WriteIntPtr(resetConsolePointer, newResetConsole);
+ IntPtr flushConsolePointer = this.engine.DangerousGetHandle("ptr_R_FlushConsole");
+ IntPtr newFlushConsole =
Marshal.GetFunctionPointerForDelegate((ptr_R_FlushConsole)FlushConsole);
+ Marshal.WriteIntPtr(flushConsolePointer, newFlushConsole);
+ IntPtr clearerrConsolePointer =
this.engine.DangerousGetHandle("ptr_R_ClearerrConsole");
+ IntPtr newClearerrConsole =
Marshal.GetFunctionPointerForDelegate((ptr_R_ClearerrConsole)ClearErrorConsole);
+ Marshal.WriteIntPtr(clearerrConsolePointer, newClearerrConsole);
+ IntPtr busyPointer = this.engine.DangerousGetHandle("ptr_R_Busy");
+ IntPtr newBusy = Marshal.GetFunctionPointerForDelegate((ptr_R_Busy)Busy);
+ Marshal.WriteIntPtr(busyPointer, newBusy);
+ IntPtr cleanUpPointer = this.engine.DangerousGetHandle("ptr_R_CleanUp");
+ IntPtr newCleanUp = Marshal.GetFunctionPointerForDelegate((ptr_R_CleanUp)CleanUp);
+ Marshal.WriteIntPtr(cleanUpPointer, newCleanUp);
+ IntPtr showFilesPointer = this.engine.DangerousGetHandle("ptr_R_ShowFiles");
+ IntPtr newShowFiles =
Marshal.GetFunctionPointerForDelegate((ptr_R_ShowFiles)ShowFiles);
+ Marshal.WriteIntPtr(showFilesPointer, newShowFiles);
+ IntPtr chooseFilePointer = this.engine.DangerousGetHandle("ptr_R_ChooseFile");
+ IntPtr newChooseFile =
Marshal.GetFunctionPointerForDelegate((ptr_R_ChooseFile)ChooseFile);
+ Marshal.WriteIntPtr(chooseFilePointer, newChooseFile);
+ IntPtr editFilePointer = this.engine.DangerousGetHandle("ptr_R_EditFile");
+ IntPtr newEditFile = Marshal.GetFunctionPointerForDelegate((ptr_R_EditFile)EditFile);
+ Marshal.WriteIntPtr(editFilePointer, newEditFile);
+ IntPtr loadHistoryPointer = this.engine.DangerousGetHandle("ptr_R_loadhistory");
+ IntPtr newLoadHistory =
Marshal.GetFunctionPointerForDelegate((ptr_R_loadhistory)LoadHistory);
+ Marshal.WriteIntPtr(loadHistoryPointer, newLoadHistory);
+ IntPtr saveHistoryPointer = this.engine.DangerousGetHandle("ptr_R_savehistory");
+ IntPtr newSaveHistory =
Marshal.GetFunctionPointerForDelegate((ptr_R_savehistory)SaveHistory);
+ Marshal.WriteIntPtr(saveHistoryPointer, newSaveHistory);
+ IntPtr addHistoryPointer = this.engine.DangerousGetHandle("ptr_R_addhistory");
+ IntPtr newAddHistory =
Marshal.GetFunctionPointerForDelegate((ptr_R_addhistory)AddHistory);
+ Marshal.WriteIntPtr(addHistoryPointer, newAddHistory);
+ }
+
+ private static string ConvertSeparator(string path)
+ {
+ return path.Replace(Path.DirectorySeparatorChar, '/');
+ }
+
+ private bool ReadConsole(string prompt, StringBuilder buffer, int count, bool history)
+ {
+ buffer.Clear();
+ string input = Device.ReadConsole(prompt, count, history);
+ buffer.Append(input).Append("\n"); // input must end with '\n\0' ('\0' is appended
during marshalling).
+ return input != null;
+ }
+
+ private void WriteConsole(string buffer, int length)
+ {
+ WriteConsoleEx(buffer, length, ConsoleOutputType.None);
+ }
+
+ private void WriteConsoleEx(string buffer, int length, ConsoleOutputType outputType)
+ {
+ Device.WriteConsole(buffer, length, outputType);
+ }
+
+ private void ShowMessage(string message)
+ {
+ Device.ShowMessage(message);
+ }
+
+ private void Busy(BusyType which)
+ {
+ Device.Busy(which);
+ }
+
+ private void Callback()
+ {
+ Device.Callback();
+ }
+
+ private YesNoCancel Ask(string question)
+ {
+ return Device.Ask(question);
+ }
+
+ private void Suicide(string message)
+ {
+ Device.Suicide(message);
+ }
+
+ private void ResetConsole()
+ {
+ Device.ResetConsole();
+ }
+
+ private void FlushConsole()
+ {
+ Device.FlushConsole();
+ }
+
+ private void ClearErrorConsole()
+ {
+ Device.ClearErrorConsole();
+ }
+
+ private void CleanUp(StartupSaveAction saveAction, int status, bool runLast)
+ {
+ Device.CleanUp(saveAction, status, runLast);
+ }
+
+ private bool ShowFiles(int count, string[] files, string[] headers, string title, bool
delete, string pager)
+ {
+ return Device.ShowFiles(files, headers, title, delete, pager);
+ }
+
+ private int ChooseFile(bool create, StringBuilder buffer, int length)
+ {
+ string path = Device.ChooseFile(create);
+ return path == null ? 0 : Encoding.ASCII.GetByteCount(path);
+ }
+
+ private void EditFile(string file)
+ {
+ Device.EditFile(file);
+ }
+
+ private IntPtr LoadHistory(IntPtr call, IntPtr operation, IntPtr args, IntPtr environment)
+ {
+ var c = new Language(Engine, call);
+ var op = new SymbolicExpression(Engine, operation);
+ var arglist = new Pairlist(Engine, args);
+ var env = new REnvironment(Engine, environment);
+ SymbolicExpression result = Device.LoadHistory(c, op, arglist, env);
+ return result.DangerousGetHandle();
+ }
+
+ private IntPtr SaveHistory(IntPtr call, IntPtr operation, IntPtr args, IntPtr environment)
+ {
+ var c = new Language(Engine, call);
+ var op = new SymbolicExpression(Engine, operation);
+ var arglist = new Pairlist(Engine, args);
+ var env = new REnvironment(Engine, environment);
+ SymbolicExpression result = Device.SaveHistory(c, op, arglist, env);
+ return result.DangerousGetHandle();
+ }
+
+ private IntPtr AddHistory(IntPtr call, IntPtr operation, IntPtr args, IntPtr environment)
+ {
+ var c = new Language(Engine, call);
+ var op = new SymbolicExpression(Engine, operation);
+ var arglist = new Pairlist(Engine, args);
+ var env = new REnvironment(Engine, environment);
+ SymbolicExpression result = Device.AddHistory(c, op, arglist, env);
+ return result.DangerousGetHandle();
+ }
+
+ #region Nested type: getValue
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate IntPtr getValue();
+
+ #endregion
+ }
+}
diff --git a/rdotnet/R.NET/Devices/ConsoleDevice.cs b/rdotnet/R.NET/Devices/ConsoleDevice.cs
new file mode 100644
index 0000000..094b5ff
--- /dev/null
+++ b/rdotnet/R.NET/Devices/ConsoleDevice.cs
@@ -0,0 +1,141 @@
+ïusing System;
+using System.IO;
+using RDotNet.Internals;
+
+namespace RDotNet.Devices
+{
+ /// <summary>
+ /// The default IO device.
+ /// </summary>
+ public class ConsoleDevice : ICharacterDevice
+ {
+ #region ICharacterDevice Members
+
+ public string ReadConsole(string prompt, int capacity, bool history)
+ {
+ Console.Write(prompt);
+ return Console.ReadLine();
+ }
+
+ public void WriteConsole(string output, int length, ConsoleOutputType outputType)
+ {
+ Console.Write(output);
+ }
+
+ public void ShowMessage(string message)
+ {
+ Console.Write(message);
+ }
+
+ public void Busy(BusyType which)
+ {}
+
+ public void Callback()
+ {}
+
+ public YesNoCancel Ask(string question)
+ {
+ Console.Write("{0} [y/n/c]: ", question);
+ string input = Console.ReadLine();
+ if (!string.IsNullOrEmpty(input))
+ {
+ switch (Char.ToLower(input[0]))
+ {
+ case 'y':
+ return YesNoCancel.Yes;
+ case 'n':
+ return YesNoCancel.No;
+ case 'c':
+ return YesNoCancel.Cancel;
+ }
+ }
+ return default(YesNoCancel);
+ }
+
+ public void Suicide(string message)
+ {
+ Console.Error.WriteLine(message);
+ CleanUp(StartupSaveAction.Suicide, 2, false);
+ }
+
+ public void ResetConsole()
+ {
+ Console.Clear();
+ }
+
+ public void FlushConsole()
+ {
+ Console.Write(string.Empty);
+ }
+
+ public void ClearErrorConsole()
+ {
+ Console.Clear();
+ }
+
+ public void CleanUp(StartupSaveAction saveAction, int status, bool runLast)
+ {
+ Environment.Exit(status);
+ }
+
+ public bool ShowFiles(string[] files, string[] headers, string title, bool delete, string
pager)
+ {
+ int count = files.Length;
+ for (int index = 0; index < count; index++)
+ {
+ try
+ {
+ Console.WriteLine(headers);
+ Console.WriteLine(File.ReadAllText(files[index]));
+ if (delete)
+ {
+ File.Delete(files[index]);
+ }
+ }
+ catch (IOException)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public string ChooseFile(bool create)
+ {
+ string path = Console.ReadLine();
+ if (string.IsNullOrWhiteSpace(path))
+ {
+ return null;
+ }
+ if (create && !File.Exists(path))
+ {
+ File.Create(path).Close();
+ }
+ if (File.Exists(path))
+ {
+ return path;
+ }
+ return null;
+ }
+
+ public void EditFile(string file)
+ {}
+
+ public SymbolicExpression LoadHistory(Language call, SymbolicExpression operation, Pairlist
args, REnvironment environment)
+ {
+ return environment.Engine.NilValue;
+ }
+
+ public SymbolicExpression SaveHistory(Language call, SymbolicExpression operation, Pairlist
args, REnvironment environment)
+ {
+ return environment.Engine.NilValue;
+ }
+
+ public SymbolicExpression AddHistory(Language call, SymbolicExpression operation, Pairlist
args, REnvironment environment)
+ {
+ return environment.Engine.NilValue;
+ }
+
+ #endregion
+ }
+}
diff --git a/rdotnet/R.NET/Devices/ICharacterDevice.cs b/rdotnet/R.NET/Devices/ICharacterDevice.cs
new file mode 100644
index 0000000..476f4c2
--- /dev/null
+++ b/rdotnet/R.NET/Devices/ICharacterDevice.cs
@@ -0,0 +1,142 @@
+ïusing RDotNet.Internals;
+
+namespace RDotNet.Devices
+{
+ /// <summary>
+ /// A console class handles user's inputs and outputs.
+ /// </summary>
+ public interface ICharacterDevice
+ {
+ /// <summary>
+ /// Read input from console.
+ /// </summary>
+ /// <param name="prompt">The prompt message.</param>
+ /// <param name="capacity">The buffer's capacity in byte.</param>
+ /// <param name="history">Whether the input should be added to any command history.</param>
+ /// <returns>The input.</returns>
+ string ReadConsole(string prompt, int capacity, bool history);
+
+ /// <summary>
+ /// Write output on console.
+ /// </summary>
+ /// <param name="output">The output message</param>
+ /// <param name="length">The output's length in byte.</param>
+ /// <param name="outputType">The output type.</param>
+ void WriteConsole(string output, int length, ConsoleOutputType outputType);
+
+ /// <summary>
+ /// Displays the message.
+ /// </summary>
+ /// <remarks>
+ /// It should be brought to the user's attention immediately.
+ /// </remarks>
+ /// <param name="message">The message.</param>
+ void ShowMessage(string message);
+
+ /// <summary>
+ /// Invokes actions.
+ /// </summary>
+ /// <param name="which">The state.</param>
+ void Busy(BusyType which);
+
+ /// <summary>
+ /// Callback function.
+ /// </summary>
+ void Callback();
+
+ /// <summary>
+ /// Asks user's decision.
+ /// </summary>
+ /// <param name="question">The question.</param>
+ /// <returns>User's decision.</returns>
+ YesNoCancel Ask(string question);
+
+ /// <summary>
+ /// Abort R environment itself as soon as possible.
+ /// </summary>
+ /// <remarks>
+ /// Only Unix.
+ /// </remarks>
+ /// <param name="message">The message.</param>
+ void Suicide(string message);
+
+ /// <summary>
+ /// Clear the console.
+ /// </summary>
+ /// <remarks>
+ /// Only Unix.
+ /// </remarks>
+ void ResetConsole();
+
+ /// <summary>
+ /// Flush the console.
+ /// </summary>
+ /// <remarks>
+ /// Only Unix.
+ /// </remarks>
+ void FlushConsole();
+
+ /// <summary>
+ /// Clear the error console.
+ /// </summary>
+ /// <remarks>
+ /// Only Unix.
+ /// </remarks>
+ void ClearErrorConsole();
+
+ /// <summary>
+ /// Invokes any actions which occur at system termination.
+ /// </summary>
+ /// <remarks>
+ /// Only Unix.
+ /// </remarks>
+ /// <param name="saveAction">The save type.</param>
+ /// <param name="status">Exit code.</param>
+ /// <param name="runLast">Whether R should execute <code>.Last</code>.</param>
+ void CleanUp(StartupSaveAction saveAction, int status, bool runLast);
+
+ /// <summary>
+ /// Displays the contents of files.
+ /// </summary>
+ /// <remarks>
+ /// Only Unix.
+ /// </remarks>
+ /// <param name="files">The file paths.</param>
+ /// <param name="headers">The header before the contents is printed.</param>
+ /// <param name="title">The window title.</param>
+ /// <param name="delete">Whether the file will be deleted.</param>
+ /// <param name="pager">The pager used.</param>
+ /// <returns></returns>
+ bool ShowFiles(string[] files, string[] headers, string title, bool delete, string pager);
+
+ /// <summary>
+ /// Chooses a file.
+ /// </summary>
+ /// <remarks>
+ /// Only Unix.
+ /// </remarks>
+ /// <param name="create">To be created.</param>
+ /// <returns>The length of input.</returns>
+ string ChooseFile(bool create);
+
+ /// <remarks>
+ /// Only Unix.
+ /// </remarks>
+ void EditFile(string file);
+
+ /// <remarks>
+ /// Only Unix.
+ /// </remarks>
+ SymbolicExpression LoadHistory(Language call, SymbolicExpression operation, Pairlist args,
REnvironment environment);
+
+ /// <remarks>
+ /// Only Unix.
+ /// </remarks>
+ SymbolicExpression SaveHistory(Language call, SymbolicExpression operation, Pairlist args,
REnvironment environment);
+
+ /// <remarks>
+ /// Only Unix.
+ /// </remarks>
+ SymbolicExpression AddHistory(Language call, SymbolicExpression operation, Pairlist args,
REnvironment environment);
+ }
+}
diff --git a/rdotnet/R.NET/Devices/NullCharacterDevice.cs b/rdotnet/R.NET/Devices/NullCharacterDevice.cs
new file mode 100644
index 0000000..c0eb773
--- /dev/null
+++ b/rdotnet/R.NET/Devices/NullCharacterDevice.cs
@@ -0,0 +1,84 @@
+ïusing System;
+using RDotNet.Internals;
+
+namespace RDotNet.Devices
+{
+ /// <summary>
+ /// The default IO device.
+ /// </summary>
+ public class NullCharacterDevice : ICharacterDevice
+ {
+ #region ICharacterDevice Members
+
+ public string ReadConsole(string prompt, int capacity, bool history)
+ {
+ return null;
+ }
+
+ public void WriteConsole(string output, int length, ConsoleOutputType outputType)
+ {}
+
+ public void ShowMessage(string message)
+ {}
+
+ public void Busy(BusyType which)
+ {}
+
+ public void Callback()
+ {}
+
+ public YesNoCancel Ask(string question)
+ {
+ return default(YesNoCancel);
+ }
+
+ public void Suicide(string message)
+ {
+ CleanUp(StartupSaveAction.Suicide, 2, false);
+ }
+
+ public void ResetConsole()
+ {}
+
+ public void FlushConsole()
+ {}
+
+ public void ClearErrorConsole()
+ {}
+
+ public void CleanUp(StartupSaveAction saveAction, int status, bool runLast)
+ {
+ Environment.Exit(status);
+ }
+
+ public bool ShowFiles(string[] files, string[] headers, string title, bool delete, string
pager)
+ {
+ return false;
+ }
+
+ public string ChooseFile(bool create)
+ {
+ return null;
+ }
+
+ public void EditFile(string file)
+ {}
+
+ public SymbolicExpression LoadHistory(Language call, SymbolicExpression operation, Pairlist
args, REnvironment environment)
+ {
+ return environment.Engine.NilValue;
+ }
+
+ public SymbolicExpression SaveHistory(Language call, SymbolicExpression operation, Pairlist
args, REnvironment environment)
+ {
+ return environment.Engine.NilValue;
+ }
+
+ public SymbolicExpression AddHistory(Language call, SymbolicExpression operation, Pairlist
args, REnvironment environment)
+ {
+ return environment.Engine.NilValue;
+ }
+
+ #endregion
+ }
+}
diff --git a/rdotnet/R.NET/Dynamic/DataFrameDynamicMeta.cs b/rdotnet/R.NET/Dynamic/DataFrameDynamicMeta.cs
new file mode 100644
index 0000000..a139353
--- /dev/null
+++ b/rdotnet/R.NET/Dynamic/DataFrameDynamicMeta.cs
@@ -0,0 +1,42 @@
+ïusing System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace RDotNet.Dynamic
+{
+ public class DataFrameDynamicMeta : SymbolicExpressionDynamicMeta
+ {
+ private static readonly Type[] IndexerNameType = new[] { typeof(string) };
+
+ public DataFrameDynamicMeta(System.Linq.Expressions.Expression parameter, DataFrame frame)
+ : base(parameter, frame)
+ {}
+
+ public override IEnumerable<string> GetDynamicMemberNames()
+ {
+ return base.GetDynamicMemberNames().Concat(GetNames());
+ }
+
+ public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
+ {
+ if (!GetNames().Contains(binder.Name))
+ {
+ return base.BindGetMember(binder);
+ }
+
+ ConstantExpression instance = System.Linq.Expressions.Expression.Constant(Value,
typeof(DataFrame));
+ ConstantExpression name = System.Linq.Expressions.Expression.Constant(binder.Name,
typeof(string));
+ PropertyInfo indexer = typeof(DataFrame).GetProperty("Item", IndexerNameType);
+ IndexExpression call = System.Linq.Expressions.Expression.Property(instance, indexer,
name);
+ return new DynamicMetaObject(call, BindingRestrictions.GetTypeRestriction(call,
typeof(DynamicVector)));
+ }
+
+ private string[] GetNames()
+ {
+ return ((DataFrame)Value).ColumnNames ?? Empty;
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Dynamic/ListDynamicMeta.cs b/rdotnet/R.NET/Dynamic/ListDynamicMeta.cs
new file mode 100644
index 0000000..b0150c2
--- /dev/null
+++ b/rdotnet/R.NET/Dynamic/ListDynamicMeta.cs
@@ -0,0 +1,42 @@
+ïusing System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace RDotNet.Dynamic
+{
+ public class ListDynamicMeta : SymbolicExpressionDynamicMeta
+ {
+ private static readonly Type[] IndexerNameType = new[] { typeof(string) };
+
+ public ListDynamicMeta(System.Linq.Expressions.Expression parameter, GenericVector list)
+ : base(parameter, list)
+ {}
+
+ public override IEnumerable<string> GetDynamicMemberNames()
+ {
+ return base.GetDynamicMemberNames().Concat(GetNames());
+ }
+
+ public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
+ {
+ if (!GetNames().Contains(binder.Name))
+ {
+ return base.BindGetMember(binder);
+ }
+
+ ConstantExpression instance = System.Linq.Expressions.Expression.Constant(Value,
typeof(GenericVector));
+ ConstantExpression name = System.Linq.Expressions.Expression.Constant(binder.Name,
typeof(string));
+ PropertyInfo indexer = typeof(GenericVector).GetProperty("Item", IndexerNameType);
+ IndexExpression call = System.Linq.Expressions.Expression.Property(instance, indexer,
name);
+ return new DynamicMetaObject(call, BindingRestrictions.GetTypeRestriction(call,
typeof(SymbolicExpression)));
+ }
+
+ private string[] GetNames()
+ {
+ return ((GenericVector)Value).Names ?? Empty;
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Dynamic/SymbolicExpressionDynamicMeta.cs
b/rdotnet/R.NET/Dynamic/SymbolicExpressionDynamicMeta.cs
new file mode 100644
index 0000000..7110d2c
--- /dev/null
+++ b/rdotnet/R.NET/Dynamic/SymbolicExpressionDynamicMeta.cs
@@ -0,0 +1,41 @@
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace RDotNet.Dynamic
+{
+ public class SymbolicExpressionDynamicMeta : DynamicMetaObject
+ {
+ protected static readonly string[] Empty = new string[0];
+
+ public SymbolicExpressionDynamicMeta(System.Linq.Expressions.Expression parameter,
SymbolicExpression expression)
+ : base(parameter, BindingRestrictions.Empty, expression)
+ {}
+
+ public override IEnumerable<string> GetDynamicMemberNames()
+ {
+ return base.GetDynamicMemberNames().Concat(GetAttributeNames());
+ }
+
+ public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
+ {
+ if (!GetAttributeNames().Contains(binder.Name))
+ {
+ return base.BindGetMember(binder);
+ }
+
+ ConstantExpression instance = System.Linq.Expressions.Expression.Constant(Value,
typeof(SymbolicExpression));
+ ConstantExpression name = System.Linq.Expressions.Expression.Constant(binder.Name,
typeof(string));
+ MethodInfo getAttribute = typeof(SymbolicExpression).GetMethod("GetAttribute");
+ MethodCallExpression call = System.Linq.Expressions.Expression.Call(instance,
getAttribute, name);
+ return new DynamicMetaObject(call, BindingRestrictions.GetTypeRestriction(call,
typeof(SymbolicExpression)));
+ }
+
+ private string[] GetAttributeNames()
+ {
+ return ((SymbolicExpression)Value).GetAttributeNames() ?? Empty;
+ }
+ }
+}
diff --git a/rdotnet/R.NET/DynamicVector.cs b/rdotnet/R.NET/DynamicVector.cs
new file mode 100644
index 0000000..30a73e1
--- /dev/null
+++ b/rdotnet/R.NET/DynamicVector.cs
@@ -0,0 +1,215 @@
+ïusing System;
+using System.Numerics;
+using System.Runtime.InteropServices;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A collection of values.
+ /// </summary>
+ /// <remarks>
+ /// This vector cannot contain more than one types of values.
+ /// Consider to use another vector class instead.
+ /// </remarks>
+ public class DynamicVector : Vector<object>
+ {
+ protected internal DynamicVector(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <remarks>
+ /// The value is converted into specific type.
+ /// </remarks>
+ /// <param name="index">The zero-based index of the element to get or set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override object this[int index]
+ {
+ get
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ IntPtr pointer = DataPointer;
+ int offset = GetOffset(index);
+ switch (Type)
+ {
+ case SymbolicExpressionType.NumericVector:
+ return ReadDouble(pointer, offset);
+ case SymbolicExpressionType.IntegerVector:
+ return ReadInt32(pointer, offset);
+ case SymbolicExpressionType.CharacterVector:
+ return ReadString(pointer, offset);
+ case SymbolicExpressionType.LogicalVector:
+ return ReadBoolean(pointer, offset);
+ case SymbolicExpressionType.RawVector:
+ return ReadByte(pointer, offset);
+ case SymbolicExpressionType.ComplexVector:
+ return ReadComplex(pointer, offset);
+ default:
+ return ReadSymbolicExpression(pointer, offset);
+ }
+ }
+ }
+ set
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ IntPtr pointer = DataPointer;
+ int offset = GetOffset(index);
+ switch (Type)
+ {
+ case SymbolicExpressionType.NumericVector:
+ WriteDouble((double)value, pointer, offset);
+ return;
+ case SymbolicExpressionType.IntegerVector:
+ WriteInt32((int)value, pointer, offset);
+ return;
+ case SymbolicExpressionType.CharacterVector:
+ WriteString((string)value, pointer, offset);
+ return;
+ case SymbolicExpressionType.LogicalVector:
+ WriteBoolean((bool)value, pointer, offset);
+ return;
+ case SymbolicExpressionType.RawVector:
+ WriteByte((byte)value, pointer, offset);
+ return;
+ case SymbolicExpressionType.ComplexVector:
+ WriteComplex((Complex)value, pointer, offset);
+ return;
+ default:
+ WriteSymbolicExpression((SymbolicExpression)value,
pointer, offset);
+ return;
+ }
+ }
+ }
+ }
+
+ protected override int DataSize
+ {
+ get
+ {
+ switch (Type)
+ {
+ case SymbolicExpressionType.NumericVector:
+ return sizeof(double);
+ case SymbolicExpressionType.IntegerVector:
+ return sizeof(int);
+ case SymbolicExpressionType.CharacterVector:
+ return Marshal.SizeOf(typeof(IntPtr));
+ case SymbolicExpressionType.LogicalVector:
+ return sizeof(int);
+ case SymbolicExpressionType.RawVector:
+ return sizeof(byte);
+ case SymbolicExpressionType.ComplexVector:
+ return Marshal.SizeOf(typeof(Complex));
+ default:
+ return Marshal.SizeOf(typeof(IntPtr));
+ }
+ }
+ }
+
+ private double ReadDouble(IntPtr pointer, int offset)
+ {
+ var data = new byte[sizeof(double)];
+ for (int byteIndex = 0; byteIndex < data.Length; byteIndex++)
+ {
+ data[byteIndex] = Marshal.ReadByte(pointer, offset + byteIndex);
+ }
+ return BitConverter.ToDouble(data, 0);
+ }
+
+ private void WriteDouble(double value, IntPtr pointer, int offset)
+ {
+ byte[] data = BitConverter.GetBytes(value);
+ for (int byteIndex = 0; byteIndex < data.Length; byteIndex++)
+ {
+ Marshal.WriteByte(pointer, offset + byteIndex, data[byteIndex]);
+ }
+ }
+
+ private int ReadInt32(IntPtr pointer, int offset)
+ {
+ return Marshal.ReadInt32(pointer, offset);
+ }
+
+ private void WriteInt32(int value, IntPtr pointer, int offset)
+ {
+ Marshal.WriteInt32(pointer, offset, value);
+ }
+
+ private string ReadString(IntPtr pointer, int offset)
+ {
+ pointer = Marshal.ReadIntPtr(pointer, offset);
+ pointer = IntPtr.Add(pointer, Marshal.SizeOf(typeof(VECTOR_SEXPREC)));
+ return Marshal.PtrToStringAnsi(pointer);
+ }
+
+ private void WriteString(string value, IntPtr pointer, int offset)
+ {
+ IntPtr stringPointer = Engine.GetFunction<Rf_mkChar>("Rf_mkChar")(value);
+ Marshal.WriteIntPtr(pointer, offset, stringPointer);
+ }
+
+ private bool ReadBoolean(IntPtr pointer, int offset)
+ {
+ int data = Marshal.ReadInt32(pointer, offset);
+ return Convert.ToBoolean(data);
+ }
+
+ private void WriteBoolean(bool value, IntPtr pointer, int offset)
+ {
+ int data = Convert.ToInt32(value);
+ Marshal.WriteInt32(pointer, offset, data);
+ }
+
+ private byte ReadByte(IntPtr pointer, int offset)
+ {
+ return Marshal.ReadByte(pointer, offset);
+ }
+
+ private void WriteByte(byte value, IntPtr pointer, int offset)
+ {
+ Marshal.WriteByte(pointer, offset, value);
+ }
+
+ private Complex ReadComplex(IntPtr pointer, int offset)
+ {
+ var data = new byte[Marshal.SizeOf(typeof(Complex))];
+ Marshal.Copy(pointer, data, 0, data.Length);
+ double real = BitConverter.ToDouble(data, 0);
+ double imaginary = BitConverter.ToDouble(data, sizeof(double));
+ return new Complex(real, imaginary);
+ }
+
+ private void WriteComplex(Complex value, IntPtr pointer, int offset)
+ {
+ byte[] real = BitConverter.GetBytes(value.Real);
+ byte[] imaginary = BitConverter.GetBytes(value.Imaginary);
+ Marshal.Copy(real, 0, pointer, real.Length);
+ pointer = IntPtr.Add(pointer, real.Length);
+ Marshal.Copy(imaginary, 0, pointer, imaginary.Length);
+ }
+
+ private SymbolicExpression ReadSymbolicExpression(IntPtr pointer, int offset)
+ {
+ IntPtr sexp = IntPtr.Add(pointer, offset);
+ return new SymbolicExpression(Engine, sexp);
+ }
+
+ private void WriteSymbolicExpression(SymbolicExpression sexp, IntPtr pointer, int offset)
+ {
+ Marshal.WriteIntPtr(pointer, offset, sexp.DangerousGetHandle());
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Environment.cs b/rdotnet/R.NET/Environment.cs
new file mode 100644
index 0000000..187191c
--- /dev/null
+++ b/rdotnet/R.NET/Environment.cs
@@ -0,0 +1,90 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// An environment object.
+ /// </summary>
+ public class REnvironment : SymbolicExpression
+ {
+ /// <summary>
+ /// Creates an environment object.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="pointer">The pointer to an environment.</param>
+ protected internal REnvironment(REngine engine, IntPtr pointer)
+ : base(engine, pointer)
+ {}
+
+ /// <summary>
+ /// Gets the parental environment.
+ /// </summary>
+ public REnvironment Parent
+ {
+ get
+ {
+ SEXPREC sexp = GetInternalStructure();
+ IntPtr parent = sexp.envsxp.enclos;
+ return Engine.CheckNil(parent) ? null : new REnvironment(Engine, parent);
+ }
+ }
+
+ /// <summary>
+ /// Gets a symbol defined in this environment.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <returns>The symbol.</returns>
+ public SymbolicExpression GetSymbol(string name)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (name == string.Empty)
+ {
+ throw new ArgumentException();
+ }
+
+ IntPtr installedName = Engine.GetFunction<Rf_install>("Rf_install")(name);
+ IntPtr value = Engine.GetFunction<Rf_findVar>("Rf_findVar")(installedName, handle);
+ if (Engine.CheckUnbound(value))
+ {
+ return null;
+ }
+
+ var sexp = (SEXPREC)Marshal.PtrToStructure(value, typeof(SEXPREC));
+ if (sexp.sxpinfo.type == SymbolicExpressionType.Promise)
+ {
+ value = Engine.GetFunction<Rf_eval>("Rf_eval")(value, handle);
+ }
+ return new SymbolicExpression(Engine, value);
+ }
+
+ /// <summary>
+ /// Defines a symbol in this environment.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="expression">The symbol.</param>
+ public void SetSymbol(string name, SymbolicExpression expression)
+ {
+ IntPtr installedName = Engine.GetFunction<Rf_install>("Rf_install")(name);
+ Engine.GetFunction<Rf_setVar>("Rf_setVar")(installedName,
expression.DangerousGetHandle(), handle);
+ }
+
+ /// <summary>
+ /// Gets the symbol names defined in this environment.
+ /// </summary>
+ /// <param name="all">Including special functions or not.</param>
+ /// <returns>Symbol names.</returns>
+ public string[] GetSymbolNames(bool all = false)
+ {
+ var symbolNames = new CharacterVector(Engine,
Engine.GetFunction<R_lsInternal>("R_lsInternal")(handle, all));
+ int length = symbolNames.Length;
+ var copy = new string[length];
+ symbolNames.CopyTo(copy, length);
+ return copy;
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Expression.cs b/rdotnet/R.NET/Expression.cs
new file mode 100644
index 0000000..f7c6536
--- /dev/null
+++ b/rdotnet/R.NET/Expression.cs
@@ -0,0 +1,62 @@
+ïusing System;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// An expression object.
+ /// </summary>
+ public class Expression : SymbolicExpression
+ {
+ /// <summary>
+ /// Creates an expression object.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="pointer">The pointer to an expression.</param>
+ protected internal Expression(REngine engine, IntPtr pointer)
+ : base(engine, pointer)
+ {}
+
+ /// <summary>
+ /// Evaluates the expression in the specified environment.
+ /// </summary>
+ /// <param name="environment">The environment.</param>
+ /// <returns>The evaluation result.</returns>
+ public SymbolicExpression Evaluate(REnvironment environment)
+ {
+ if (environment == null)
+ {
+ throw new ArgumentNullException("environment");
+ }
+ if (Engine != environment.Engine)
+ {
+ throw new ArgumentException(null, "environment");
+ }
+
+ return new SymbolicExpression(Engine, Engine.GetFunction<Rf_eval>("Rf_eval")(handle,
environment.DangerousGetHandle()));
+ }
+
+ /// <summary>
+ /// Evaluates the expression in the specified environment.
+ /// </summary>
+ /// <param name="environment">The environment.</param>
+ /// <param name="result">The evaluation result, or <c>null</c> if the evaluation
failed</param>
+ /// <returns><c>True</c> if the evaluation succeeded.</returns>
+ public bool TryEvaluate(REnvironment environment, out SymbolicExpression result)
+ {
+ if (environment == null)
+ {
+ throw new ArgumentNullException("environment");
+ }
+ if (Engine != environment.Engine)
+ {
+ throw new ArgumentException(null, "environment");
+ }
+
+ bool errorOccurred;
+ IntPtr pointer = Engine.GetFunction<R_tryEval>("R_tryEval")(handle,
environment.DangerousGetHandle(), out errorOccurred);
+ result = errorOccurred ? null : new SymbolicExpression(Engine, pointer);
+ return !errorOccurred;
+ }
+ }
+}
diff --git a/rdotnet/R.NET/ExpressionVector.cs b/rdotnet/R.NET/ExpressionVector.cs
new file mode 100644
index 0000000..46079c0
--- /dev/null
+++ b/rdotnet/R.NET/ExpressionVector.cs
@@ -0,0 +1,56 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+
+namespace RDotNet
+{
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class ExpressionVector : Vector<Expression>
+ {
+ /// <summary>
+ /// Creates a new instance for an expression vector.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to an expression vector.</param>
+ internal ExpressionVector(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ public override Expression this[int index]
+ {
+ get
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(index);
+ IntPtr pointer = Marshal.ReadIntPtr(DataPointer, offset);
+ return new Expression(Engine, pointer);
+ }
+ }
+ set
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(index);
+ Marshal.WriteIntPtr(DataPointer, offset, (value ??
Engine.NilValue).DangerousGetHandle());
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of a pointer in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get { return Marshal.SizeOf(typeof(IntPtr)); }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Function.cs b/rdotnet/R.NET/Function.cs
new file mode 100644
index 0000000..fa4c482
--- /dev/null
+++ b/rdotnet/R.NET/Function.cs
@@ -0,0 +1,26 @@
+ïusing System;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A function is one of closure, built-in function, or special function.
+ /// </summary>
+ public abstract class Function : SymbolicExpression
+ {
+ /// <summary>
+ /// Creates a function object.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="pointer">The pointer.</param>
+ protected Function(REngine engine, IntPtr pointer)
+ : base(engine, pointer)
+ {}
+
+ /// <summary>
+ /// Executes the function.
+ /// </summary>
+ /// <param name="args">The arguments.</param>
+ /// <returns>The return value.</returns>
+ public abstract SymbolicExpression Invoke(SymbolicExpression[] args);
+ }
+}
diff --git a/rdotnet/R.NET/GenericVector.cs b/rdotnet/R.NET/GenericVector.cs
new file mode 100644
index 0000000..411d436
--- /dev/null
+++ b/rdotnet/R.NET/GenericVector.cs
@@ -0,0 +1,97 @@
+ïusing System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Dynamic;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A generic list. This is also known as list in R.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class GenericVector : Vector<SymbolicExpression>
+ {
+ /// <summary>
+ /// Creates a new empty GenericVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="length">The length.</param>
+ public GenericVector(REngine engine, int length)
+ : base(engine,
engine.GetFunction<Rf_allocVector>("Rf_allocVector")(SymbolicExpressionType.List, length))
+ {}
+
+ /// <summary>
+ /// Creates a new GenericVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="list">The values.</param>
+ public GenericVector(REngine engine, IEnumerable<SymbolicExpression> list)
+ : base(engine, SymbolicExpressionType.List, list)
+ {}
+
+ /// <summary>
+ /// Creates a new instance for a list.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a list.</param>
+ protected internal GenericVector(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index of the element to get or set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override SymbolicExpression this[int index]
+ {
+ get
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(index);
+ IntPtr pointer = Marshal.ReadIntPtr(DataPointer, offset);
+ return new SymbolicExpression(Engine, pointer);
+ }
+ }
+ set
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(index);
+ Marshal.WriteIntPtr(DataPointer, offset, (value ??
Engine.NilValue).DangerousGetHandle());
+ }
+ }
+ }
+
+ protected override int DataSize
+ {
+ get { return Marshal.SizeOf(typeof(IntPtr)); }
+ }
+
+ /// <summary>
+ /// Converts into a <see cref="RDotNet.Pairlist"/>.
+ /// </summary>
+ /// <returns>The pairlist.</returns>
+ public Pairlist ToPairlist()
+ {
+ return new Pairlist(Engine,
Engine.GetFunction<Rf_VectorToPairList>("Rf_VectorToPairList")(handle));
+ }
+
+ public override DynamicMetaObject GetMetaObject(System.Linq.Expressions.Expression parameter)
+ {
+ return new ListDynamicMeta(parameter, this);
+ }
+ }
+}
diff --git a/rdotnet/R.NET/IntegerMatrix.cs b/rdotnet/R.NET/IntegerMatrix.cs
new file mode 100644
index 0000000..648be64
--- /dev/null
+++ b/rdotnet/R.NET/IntegerMatrix.cs
@@ -0,0 +1,97 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A matrix of integers from <c>-2^31 + 1</c> to <c>2^31 - 1</c>.
+ /// </summary>
+ /// <remarks>
+ /// The minimum value of IntegerVector is different from that of System.Int32 in .NET Framework.
+ /// </remarks>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class IntegerMatrix : Matrix<int>
+ {
+ /// <summary>
+ /// Creates a new empty IntegerMatrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="rowCount">The row size.</param>
+ /// <param name="columnCount">The column size.</param>
+ /// <seealso cref="REngineExtension.CreateIntegerMatrix(REngine, int, int)"/>
+ public IntegerMatrix(REngine engine, int rowCount, int columnCount)
+ : base(engine, SymbolicExpressionType.IntegerVector, rowCount, columnCount)
+ {}
+
+ /// <summary>
+ /// Creates a new IntegerMatrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="matrix">The values.</param>
+ /// <seealso cref="REngineExtension.CreateIntegerMatrix(REngine, int[,])"/>
+ public IntegerMatrix(REngine engine, int[,] matrix)
+ : base(engine, SymbolicExpressionType.IntegerVector, matrix)
+ {}
+
+ /// <summary>
+ /// Creates a new instance for an integer matrix.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to an integer matrix.</param>
+ protected internal IntegerMatrix(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="rowIndex">The zero-based rowIndex index of the element to get or set.</param>
+ /// <param name="columnIndex">The zero-based columnIndex index of the element to get or
set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override int this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex < 0 || RowCount <= rowIndex)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex < 0 || ColumnCount <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(rowIndex, columnIndex);
+ return Marshal.ReadInt32(DataPointer, offset);
+ }
+ }
+ set
+ {
+ if (rowIndex < 0 || RowCount <= rowIndex)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex < 0 || ColumnCount <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(rowIndex, columnIndex);
+ Marshal.WriteInt32(DataPointer, offset, value);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of an integer in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get { return sizeof(int); }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/IntegerVector.cs b/rdotnet/R.NET/IntegerVector.cs
new file mode 100644
index 0000000..0f225db
--- /dev/null
+++ b/rdotnet/R.NET/IntegerVector.cs
@@ -0,0 +1,131 @@
+ïusing System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A collection of integers from <c>-2^31 + 1</c> to <c>2^31 - 1</c>.
+ /// </summary>
+ /// <remarks>
+ /// The minimum value of IntegerVector is different from that of System.Int32 in .NET Framework.
+ /// </remarks>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class IntegerVector : Vector<int>
+ {
+ /// <summary>
+ /// Creates a new empty IntegerVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="length">The length.</param>
+ /// <seealso cref="REngineExtension.CreateIntegerVector(REngine, int)"/>
+ public IntegerVector(REngine engine, int length)
+ : base(engine, SymbolicExpressionType.IntegerVector, length)
+ {}
+
+ /// <summary>
+ /// Creates a new IntegerVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="vector">The values.</param>
+ /// <seealso cref="REngineExtension.CreateIntegerVector(REngine, IEnumerable{int})"/>
+ public IntegerVector(REngine engine, IEnumerable<int> vector)
+ : base(engine, SymbolicExpressionType.IntegerVector, vector)
+ {}
+
+ /// <summary>
+ /// Creates a new IntegerVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="vector">The values.</param>
+ /// <seealso cref="REngineExtension.CreateIntegerVector(REngine, int[])"/>
+ public IntegerVector(REngine engine, int[] vector)
+ : base(engine, SymbolicExpressionType.IntegerVector, vector.Length)
+ {
+ Marshal.Copy(vector, 0, DataPointer, vector.Length);
+ }
+
+ /// <summary>
+ /// Creates a new instance for an integer vector.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to an integer vector.</param>
+ protected internal IntegerVector(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index of the element to get or set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override int this[int index]
+ {
+ get
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(index);
+ return Marshal.ReadInt32(DataPointer, offset);
+ }
+ }
+ set
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(index);
+ Marshal.WriteInt32(DataPointer, offset, value);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of an integer in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get { return sizeof(int); }
+ }
+
+ /// <summary>
+ /// Copies the elements to the specified array.
+ /// </summary>
+ /// <param name="destination">The destination array.</param>
+ /// <param name="length">The length to copy.</param>
+ /// <param name="sourceIndex">The first index of the vector.</param>
+ /// <param name="destinationIndex">The first index of the destination array.</param>
+ public new void CopyTo(int[] destination, int length, int sourceIndex = 0, int
destinationIndex = 0)
+ {
+ if (destination == null)
+ {
+ throw new ArgumentNullException("destination");
+ }
+ if (length < 0)
+ {
+ throw new IndexOutOfRangeException("length");
+ }
+ if (sourceIndex < 0 || Length < sourceIndex + length)
+ {
+ throw new IndexOutOfRangeException("sourceIndex");
+ }
+ if (destinationIndex < 0 || destination.Length < destinationIndex + length)
+ {
+ throw new IndexOutOfRangeException("destinationIndex");
+ }
+
+ int offset = GetOffset(sourceIndex);
+ IntPtr pointer = IntPtr.Add(DataPointer, offset);
+ Marshal.Copy(pointer, destination, destinationIndex, length);
+ }
+ }
+}
diff --git a/rdotnet/R.NET/InternalString.cs b/rdotnet/R.NET/InternalString.cs
new file mode 100644
index 0000000..eb984b21
--- /dev/null
+++ b/rdotnet/R.NET/InternalString.cs
@@ -0,0 +1,48 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// Internal string.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class InternalString : SymbolicExpression
+ {
+ /// <summary>
+ /// Creates a new instance.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="pointer">The pointer to a string.</param>
+ public InternalString(REngine engine, IntPtr pointer)
+ : base(engine, pointer)
+ {}
+
+ /// <summary>
+ /// Creates a new instance.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="s">The string</param>
+ public InternalString(REngine engine, string s)
+ : base(engine, engine.GetFunction<Rf_mkChar>("Rf_mkChar")(s))
+ {}
+
+ /// <summary>
+ /// Converts to the string into .NET Framework string.
+ /// </summary>
+ /// <param name="s">The R string.</param>
+ /// <returns>The .NET Framework string.</returns>
+ public static implicit operator string(InternalString s)
+ {
+ return s.ToString();
+ }
+
+ public override string ToString()
+ {
+ IntPtr pointer = IntPtr.Add(handle, Marshal.SizeOf(typeof(VECTOR_SEXPREC)));
+ return Marshal.PtrToStringAnsi(pointer);
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Internals/BusyType.cs b/rdotnet/R.NET/Internals/BusyType.cs
new file mode 100644
index 0000000..05fd721
--- /dev/null
+++ b/rdotnet/R.NET/Internals/BusyType.cs
@@ -0,0 +1,18 @@
+ïnamespace RDotNet.Internals
+{
+ /// <summary>
+ /// Type of R's working.
+ /// </summary>
+ public enum BusyType
+ {
+ /// <summary>
+ /// Terminated states of business.
+ /// </summary>
+ None = 0,
+
+ /// <summary>
+ /// Embarks on an extended computation
+ /// </summary>
+ ExtendedComputation = 1,
+ }
+}
diff --git a/rdotnet/R.NET/Internals/ConsoleOutputType.cs b/rdotnet/R.NET/Internals/ConsoleOutputType.cs
new file mode 100644
index 0000000..884515a
--- /dev/null
+++ b/rdotnet/R.NET/Internals/ConsoleOutputType.cs
@@ -0,0 +1,13 @@
+ïnamespace RDotNet.Internals
+{
+ /// <summary>
+ /// Specifies console to output.
+ /// </summary>
+ public enum ConsoleOutputType
+ {
+ /// <summary>
+ /// The default value.
+ /// </summary>
+ None = 0,
+ }
+}
diff --git a/rdotnet/R.NET/Internals/Delegates.cs b/rdotnet/R.NET/Internals/Delegates.cs
new file mode 100644
index 0000000..44c0a64
--- /dev/null
+++ b/rdotnet/R.NET/Internals/Delegates.cs
@@ -0,0 +1,136 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using UnixRStart = RDotNet.Internals.Unix.RStart;
+using WindowsRStart = RDotNet.Internals.Windows.RStart;
+
+namespace RDotNet.Internals
+{
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void R_setStartTime();
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate int Rf_initialize_R(int ac, string[] argv);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void R_SetParams_Unix(ref UnixRStart start);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void R_SetParams_Windows(ref WindowsRStart start);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void R_set_command_line_arguments(int argc, string[] argv);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void setup_Rmainloop();
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate int Rf_initEmbeddedR(int argc, string[] argv);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void Rf_endEmbeddedR(int fatal);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_protect(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void Rf_unprotect(int count);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void Rf_unprotect_ptr(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_install(string s);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_mkString(string s);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_mkChar(string s);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_allocVector(SymbolicExpressionType type, int length);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_coerceVector(IntPtr sexp, SymbolicExpressionType type);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool Rf_isVector(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate int Rf_length(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_allocMatrix(SymbolicExpressionType type, int rowCount, int columnCount);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool Rf_isMatrix(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate int Rf_nrows(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate int Rf_ncols(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_allocList(int length);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool Rf_isList(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_eval(IntPtr statement, IntPtr environment);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr R_tryEval(IntPtr statement, IntPtr environment, out bool errorOccurred);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr R_ParseVector(IntPtr statement, int statementCount, out ParseStatus status,
IntPtr _);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_findVar(IntPtr name, IntPtr environment);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void Rf_setVar(IntPtr name, IntPtr value, IntPtr environment);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_getAttrib(IntPtr sexp, IntPtr name);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_setAttrib(IntPtr sexp, IntPtr name, IntPtr value);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool Rf_isEnvironment(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool Rf_isExpression(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool Rf_isSymbol(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool Rf_isLanguage(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool Rf_isFunction(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr R_lsInternal(IntPtr environment, bool all);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_applyClosure(IntPtr call, IntPtr value, IntPtr arguments, IntPtr
environment, IntPtr suppliedEnvironment);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_VectorToPairList(IntPtr sexp);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_allocSExp(SymbolicExpressionType type);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_cons(IntPtr sexp, IntPtr next);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr Rf_lcons(IntPtr sexp, IntPtr next);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void R_gc();
+}
diff --git a/rdotnet/R.NET/Internals/OutputMode.cs b/rdotnet/R.NET/Internals/OutputMode.cs
new file mode 100644
index 0000000..1365a57
--- /dev/null
+++ b/rdotnet/R.NET/Internals/OutputMode.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace RDotNet.Internals
+{
+ /// <summary>
+ /// Specifies output mode.
+ /// </summary>
+ [Flags]
+ public enum OutputMode
+ {
+ /// <summary>
+ /// No option.
+ /// </summary>
+ None = 0x0,
+
+ /// <summary>
+ /// Quiet mode.
+ /// </summary>
+ Quiet = 0x1,
+
+ /// <summary>
+ /// Slave mode.
+ /// </summary>
+ Slave = 0x2,
+
+ /// <summary>
+ /// Verbose mode.
+ /// </summary>
+ Verbose = 0x4,
+ }
+}
diff --git a/rdotnet/R.NET/Internals/ParseStatus.cs b/rdotnet/R.NET/Internals/ParseStatus.cs
new file mode 100644
index 0000000..84fb3ae
--- /dev/null
+++ b/rdotnet/R.NET/Internals/ParseStatus.cs
@@ -0,0 +1,46 @@
+ïnamespace RDotNet.Internals
+{
+ /// <summary>
+ /// Parsing status enumeration.
+ /// </summary>
+ public enum ParseStatus
+ {
+ /// <summary>
+ /// The default value.
+ /// </summary>
+ Null,
+
+ /// <summary>
+ /// No error.
+ /// </summary>
+ OK,
+
+ /// <summary>
+ /// Statement is incomplete.
+ /// </summary>
+ Incomplete,
+
+ /// <summary>
+ /// Error occurred.
+ /// </summary>
+ Error,
+
+ /// <summary>
+ /// EOF.
+ /// </summary>
+ EOF,
+
+ //#region Original Definitions
+ //[Obsolete("Use ParseStatus.Null instead.")]
+ //PARSE_NULL = Null,
+ //[Obsolete("Use ParseStatus.OK instead.")]
+ //PARSE_OK = OK,
+ //[Obsolete("Use ParseStatus.Incomplete instead.")]
+ //PARSE_INCOMPLETE = Incomplete,
+ //[Obsolete("Use ParseStatus.Error instead.")]
+ //PARSE_ERROR = Error,
+ //[Obsolete("Use ParseStatus.EOF instead.")]
+ //PARSE_EOF = EOF,
+ //#endregion
+ }
+}
diff --git a/rdotnet/R.NET/Internals/SEXPREC.cs b/rdotnet/R.NET/Internals/SEXPREC.cs
new file mode 100644
index 0000000..70a2ca6
--- /dev/null
+++ b/rdotnet/R.NET/Internals/SEXPREC.cs
@@ -0,0 +1,137 @@
+ïusing System;
+using System.Runtime.InteropServices;
+
+namespace RDotNet.Internals
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct SEXPREC
+ {
+ private SEXPREC_HEADER header;
+ private u u;
+
+ public sxpinfo sxpinfo
+ {
+ get { return this.header.sxpinfo; }
+ }
+
+ public IntPtr attrib
+ {
+ get { return this.header.attrib; }
+ }
+
+ public IntPtr gengc_next_node
+ {
+ get { return this.header.gengc_next_node; }
+ }
+
+ public IntPtr gengc_prev_node
+ {
+ get { return this.header.gengc_prev_node; }
+ }
+
+ internal primsxp primsxp
+ {
+ get { return this.u.primsxp; }
+ }
+
+ internal symsxp symsxp
+ {
+ get { return this.u.symsxp; }
+ }
+
+ internal listsxp listsxp
+ {
+ get { return this.u.listsxp; }
+ }
+
+ internal envsxp envsxp
+ {
+ get { return this.u.envsxp; }
+ }
+
+ internal closxp closxp
+ {
+ get { return this.u.closxp; }
+ }
+
+ internal promsxp promsxp
+ {
+ get { return this.u.promsxp; }
+ }
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ internal struct u
+ {
+ [FieldOffset(0)]
+ internal primsxp primsxp;
+
+ [FieldOffset(0)]
+ internal symsxp symsxp;
+
+ [FieldOffset(0)]
+ internal listsxp listsxp;
+
+ [FieldOffset(0)]
+ internal envsxp envsxp;
+
+ [FieldOffset(0)]
+ internal closxp closxp;
+
+ [FieldOffset(0)]
+ internal promsxp promsxp;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct vecsxp
+ {
+ public int length;
+ public int truelength;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct primsxp
+ {
+ public int offset;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct symsxp
+ {
+ public IntPtr pname;
+ public IntPtr value;
+ public IntPtr @internal;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct listsxp
+ {
+ public IntPtr carval;
+ public IntPtr cdrval;
+ public IntPtr tagval;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct envsxp
+ {
+ public IntPtr frame;
+ public IntPtr enclos;
+ public IntPtr hashtab;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct closxp
+ {
+ public IntPtr formals;
+ public IntPtr body;
+ public IntPtr env;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct promsxp
+ {
+ public IntPtr value;
+ public IntPtr expr;
+ public IntPtr env;
+ }
+}
diff --git a/rdotnet/R.NET/Internals/SEXPREC_HEADER.cs b/rdotnet/R.NET/Internals/SEXPREC_HEADER.cs
new file mode 100644
index 0000000..997e5e9
--- /dev/null
+++ b/rdotnet/R.NET/Internals/SEXPREC_HEADER.cs
@@ -0,0 +1,14 @@
+ïusing System;
+using System.Runtime.InteropServices;
+
+namespace RDotNet.Internals
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct SEXPREC_HEADER
+ {
+ public sxpinfo sxpinfo;
+ public IntPtr attrib;
+ public IntPtr gengc_next_node;
+ public IntPtr gengc_prev_node;
+ }
+}
diff --git a/rdotnet/R.NET/Internals/SaveActions.cs b/rdotnet/R.NET/Internals/SaveActions.cs
new file mode 100644
index 0000000..897b8d5
--- /dev/null
+++ b/rdotnet/R.NET/Internals/SaveActions.cs
@@ -0,0 +1,54 @@
+ïnamespace RDotNet.Internals
+{
+ /// <summary>
+ /// Specifies the restore action.
+ /// </summary>
+ public enum StartupRestoreAction
+ {
+ /// <summary>
+ /// Not restoring.
+ /// </summary>
+ NoRestore = 0,
+
+ /// <summary>
+ /// Restoring.
+ /// </summary>
+ Restore = 1,
+
+ /// <summary>
+ /// The default value.
+ /// </summary>
+ Default = 2,
+ }
+
+ /// <summary>
+ /// Specifies the save action.
+ /// </summary>
+ public enum StartupSaveAction
+ {
+ /// <summary>
+ /// The default value.
+ /// </summary>
+ Default = 2,
+
+ /// <summary>
+ /// No saving.
+ /// </summary>
+ NoSave = 3,
+
+ /// <summary>
+ /// Saving.
+ /// </summary>
+ Save = 4,
+
+ /// <summary>
+ /// Asking user.
+ /// </summary>
+ Ask = 5,
+
+ /// <summary>
+ /// Terminates without any actions.
+ /// </summary>
+ Suicide = 6,
+ }
+}
diff --git a/rdotnet/R.NET/Internals/SymbolicExpressionType.cs
b/rdotnet/R.NET/Internals/SymbolicExpressionType.cs
new file mode 100644
index 0000000..7affba6
--- /dev/null
+++ b/rdotnet/R.NET/Internals/SymbolicExpressionType.cs
@@ -0,0 +1,188 @@
+ïusing System;
+
+namespace RDotNet.Internals
+{
+ /// <summary>
+ /// SEXPTYPE enumeration.
+ /// </summary>
+ public enum SymbolicExpressionType
+ {
+ /// <summary>
+ /// Null.
+ /// </summary>
+ Null = 0,
+
+ /// <summary>
+ /// Symbols.
+ /// </summary>
+ Symbol = 1,
+
+ /// <summary>
+ /// Pairlists.
+ /// </summary>
+ Pairlist = 2,
+
+ /// <summary>
+ /// Closures.
+ /// </summary>
+ Closure = 3,
+
+ /// <summary>
+ /// Environments.
+ /// </summary>
+ Environment = 4,
+
+ /// <summary>
+ /// To be evaluated.
+ /// </summary>
+ Promise = 5,
+
+ /// <summary>
+ /// Pairlists for function calls.
+ /// </summary>
+ LanguageObject = 6,
+
+ /// <summary>
+ /// Special functions.
+ /// </summary>
+ SpecialFunction = 7,
+
+ /// <summary>
+ /// Builtin functions.
+ /// </summary>
+ BuiltinFunction = 8,
+
+ /// <summary>
+ /// Internal character string.
+ /// </summary>
+ InternalCharacterString = 9,
+
+ /// <summary>
+ /// Boolean vectors.
+ /// </summary>
+ LogicalVector = 10,
+
+ /// <summary>
+ /// Integer vectors.
+ /// </summary>
+ IntegerVector = 13,
+
+ /// <summary>
+ /// Numeric vectors.
+ /// </summary>
+ NumericVector = 14,
+
+ /// <summary>
+ /// Complex number vectors.
+ /// </summary>
+ ComplexVector = 15,
+
+ /// <summary>
+ /// Character vectors.
+ /// </summary>
+ CharacterVector = 16,
+
+ /// <summary>
+ /// Dot-dot-dot object.
+ /// </summary>
+ DotDotDotObject = 17,
+
+ /// <summary>
+ /// Place holders for any type.
+ /// </summary>
+ Any = 18,
+
+ /// <summary>
+ /// Generic vectors.
+ /// </summary>
+ List = 19,
+
+ /// <summary>
+ /// Expression vectors.
+ /// </summary>
+ ExpressionVector = 20,
+
+ /// <summary>
+ /// Byte code.
+ /// </summary>
+ ByteCode = 21,
+
+ /// <summary>
+ /// External pointer.
+ /// </summary>
+ ExternalPointer = 22,
+
+ /// <summary>
+ /// Weak reference.
+ /// </summary>
+ WeakReference = 23,
+
+ /// <summary>
+ /// Raw vectors.
+ /// </summary>
+ RawVector = 24,
+
+ /// <summary>
+ /// S4 classes.
+ /// </summary>
+ S4 = 25,
+
+ #region Original Definitions
+
+ //[Obsolete("Use SEXPTYPE.Null instead.")]
+ //NILSXP = Null,
+ //[Obsolete("Use SEXPTYPE.Symbol istead.")]
+ //SYMSXP = Symbol,
+ //[Obsolete("Use SEXPTYPE.Pairlist istead.")]
+ //LISTSXP = Pairlist,
+ //[Obsolete("Use SEXPTYPE.Closure instead.")]
+ //CLOSXP = Closure,
+ //[Obsolete("Use SEXPTYPE.Environment instead.")]
+ //ENVSXP = Environment,
+ //[Obsolete("Use SEXPTYPE.Promise instead.")]
+ //PROMSXP = Promise,
+ //[Obsolete("Use SEXPTYPE.LanguageObject instead.")]
+ //LANGSXP = LanguageObject,
+ //[Obsolete("Use SEXPTYPE.SpecialFunction instead.")]
+ //SPECIALSXP = SpecialFunction,
+ //[Obsolete("Use SEXPTYPE.BuiltinFunction instead.")]
+ //BUILTINSXP = BuiltinFunction,
+ //[Obsolete("Use SEXPTYPE.InternalCharacterString instead.")]
+ //CHARSXP = InternalCharacterString,
+ //[Obsolete("Use SEXPTYPE.LogicalVector instead.")]
+ //LGLSXP = LogicalVector,
+ //[Obsolete("Use SEXPTYPE.IntegerVector instead.")]
+ //INTSXP = IntegerVector,
+ //[Obsolete("Use SEXPTYPE.NumericVector instead.")]
+ //REALSXP = NumericVector,
+ //[Obsolete("Use SEXPTYPE.ComplexVector instead.")]
+ //CPLXSXP = ComplexVector,
+ //[Obsolete("Use SEXPTYPE.CharacterVector instead.")]
+ //STRSXP = CharacterVector,
+ //[Obsolete("Use SEXPTYPE.DotDotDotObject instead.")]
+ //DOTSXP = DotDotDotObject,
+ //[Obsolete("Use SEXPTYPE.Any instead.")]
+ //ANYSXP = Any,
+ //[Obsolete("Use SEXPTYPE.List instead.")]
+ //VECSXP = List,
+ //[Obsolete("Use SEXPTYPE.ExpressionVector instead.")]
+ //EXPRSXP = ExpressionVector,
+ //[Obsolete("Use SEXPTYPE.ByteCode instead.")]
+ //BCODESXP = ByteCode,
+ //[Obsolete("Use SEXPTYPE.ExternalPointer instead.")]
+ //EXTPTRSXP = ExternalPointer,
+ //[Obsolete("Use SEXPTYPE.WeakReference instead.")]
+ //WEAKREFSXP = WeakReference,
+ //[Obsolete("Use SEXPTYPE.RawVector instead.")]
+ //RAWSXP = RawVector,
+ //[Obsolete("Use SEXPTYPE.S4 instead.")]
+ //S4SXP = S4,
+ /// <summary>
+ /// Closures, builtin functions or special functions.
+ /// </summary>
+ [Obsolete("Use SEXPTYPE.Closure instead. But, note that value is different from
SEXPTYPE.Closure.")]
+ FUNSXP = 99,
+
+ #endregion
+ }
+}
diff --git a/rdotnet/R.NET/Internals/Unix/Delegates.cs b/rdotnet/R.NET/Internals/Unix/Delegates.cs
new file mode 100644
index 0000000..fa7e06d
--- /dev/null
+++ b/rdotnet/R.NET/Internals/Unix/Delegates.cs
@@ -0,0 +1,57 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace RDotNet.Internals.Unix
+{
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ptr_R_Suicide([In] [MarshalAs(UnmanagedType.LPStr)] string message);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ptr_R_ShowMessage([In] [MarshalAs(UnmanagedType.LPStr)] string message);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ [return : MarshalAs(UnmanagedType.Bool)]
+ internal delegate bool ptr_R_ReadConsole([In] [MarshalAs(UnmanagedType.LPStr)] string prompt,
[MarshalAs(UnmanagedType.LPStr)] StringBuilder buffer, int length, [MarshalAs(UnmanagedType.Bool)] bool
history);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ptr_R_WriteConsole([In] [MarshalAs(UnmanagedType.LPStr)] string buffer, int
length);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ptr_R_WriteConsoleEx([In] [MarshalAs(UnmanagedType.LPStr)] string buffer, int
length, ConsoleOutputType outputType);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ptr_R_ResetConsole();
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ptr_R_FlushConsole();
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ptr_R_ClearerrConsole();
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ptr_R_Busy(BusyType which);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ptr_R_CleanUp(StartupSaveAction saveAction, int status,
[MarshalAs(UnmanagedType.Bool)] bool runLast);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ [return : MarshalAs(UnmanagedType.Bool)]
+ internal delegate bool ptr_R_ShowFiles(int count, [In] [MarshalAs(UnmanagedType.LPArray, ArraySubType
= UnmanagedType.LPStr)] string[] files, [In] [MarshalAs(UnmanagedType.LPArray, ArraySubType =
UnmanagedType.LPStr)] string[] headers, [In] [MarshalAs(UnmanagedType.LPStr)] string title,
[MarshalAs(UnmanagedType.Bool)] bool delete, [In] [MarshalAs(UnmanagedType.LPStr)] string pager);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ [return : MarshalAs(UnmanagedType.Bool)]
+ internal delegate int ptr_R_ChooseFile([MarshalAs(UnmanagedType.Bool)] bool create, StringBuilder
buffer, int length);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ptr_R_EditFile([MarshalAs(UnmanagedType.LPStr)] string file);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr ptr_R_loadhistory(IntPtr call, IntPtr operation, IntPtr args, IntPtr
environment);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr ptr_R_savehistory(IntPtr call, IntPtr operation, IntPtr args, IntPtr
environment);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate IntPtr ptr_R_addhistory(IntPtr call, IntPtr operation, IntPtr args, IntPtr
environment);
+}
diff --git a/rdotnet/R.NET/Internals/Unix/RStart.cs b/rdotnet/R.NET/Internals/Unix/RStart.cs
new file mode 100644
index 0000000..edc70c4
--- /dev/null
+++ b/rdotnet/R.NET/Internals/Unix/RStart.cs
@@ -0,0 +1,41 @@
+ïusing System;
+using System.Runtime.InteropServices;
+
+namespace RDotNet.Internals.Unix
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct RStart
+ {
+ [MarshalAs(UnmanagedType.Bool)]
+ public bool R_Quiet;
+
+ [MarshalAs(UnmanagedType.Bool)]
+ public bool R_Slave;
+
+ [MarshalAs(UnmanagedType.Bool)]
+ public bool R_Interactive;
+
+ [MarshalAs(UnmanagedType.Bool)]
+ public bool R_Verbose;
+
+ [MarshalAs(UnmanagedType.Bool)]
+ public bool LoadSiteFile;
+
+ [MarshalAs(UnmanagedType.Bool)]
+ public bool LoadInitFile;
+
+ [MarshalAs(UnmanagedType.Bool)]
+ public bool DebugInitFile;
+
+ public StartupRestoreAction RestoreAction;
+ public StartupSaveAction SaveAction;
+ internal UIntPtr vsize;
+ internal UIntPtr nsize;
+ internal UIntPtr max_vsize;
+ internal UIntPtr max_nsize;
+ internal UIntPtr ppsize;
+
+ [MarshalAs(UnmanagedType.Bool)]
+ public bool NoRenviron;
+ }
+}
diff --git a/rdotnet/R.NET/Internals/VECTOR_SEXPREC.cs b/rdotnet/R.NET/Internals/VECTOR_SEXPREC.cs
new file mode 100644
index 0000000..9fb07cf
--- /dev/null
+++ b/rdotnet/R.NET/Internals/VECTOR_SEXPREC.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace RDotNet.Internals
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct VECTOR_SEXPREC
+ {
+ private SEXPREC_HEADER header;
+ private vecsxp vecsxp;
+
+ public sxpinfo sxpinfo
+ {
+ get
+ {
+ return header.sxpinfo;
+ }
+ }
+
+ public IntPtr attrib
+ {
+ get
+ {
+ return header.attrib;
+ }
+ }
+
+ public IntPtr gengc_next_node
+ {
+ get
+ {
+ return header.gengc_next_node;
+ }
+ }
+
+ public IntPtr gengc_prev_node
+ {
+ get
+ {
+ return header.gengc_prev_node;
+ }
+ }
+
+ public int Length
+ {
+ get
+ {
+ return vecsxp.length;
+ }
+ }
+
+ public int TrueLength
+ {
+ get
+ {
+ return vecsxp.truelength;
+ }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Internals/Windows/Delegates.cs b/rdotnet/R.NET/Internals/Windows/Delegates.cs
new file mode 100644
index 0000000..5e87e20
--- /dev/null
+++ b/rdotnet/R.NET/Internals/Windows/Delegates.cs
@@ -0,0 +1,27 @@
+ïusing System.Runtime.InteropServices;
+using System.Text;
+
+namespace RDotNet.Internals.Windows
+{
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ [return : MarshalAs(UnmanagedType.Bool)]
+ internal delegate bool blah1([In] [MarshalAs(UnmanagedType.LPStr)] string prompt,
[MarshalAs(UnmanagedType.LPStr)] StringBuilder buffer, int length, [MarshalAs(UnmanagedType.Bool)] bool
history);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void blah2([In] [MarshalAs(UnmanagedType.LPStr)] string buffer, int length);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void blah3();
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void blah4([In] [MarshalAs(UnmanagedType.LPStr)] string message);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate YesNoCancel blah5([In] [MarshalAs(UnmanagedType.LPStr)] string question);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void blah6(BusyType which);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void blah7([In] [MarshalAs(UnmanagedType.LPStr)] string buffer, int length,
ConsoleOutputType outputType);
+}
diff --git a/rdotnet/R.NET/Internals/Windows/RStart.cs b/rdotnet/R.NET/Internals/Windows/RStart.cs
new file mode 100644
index 0000000..e3623a6
--- /dev/null
+++ b/rdotnet/R.NET/Internals/Windows/RStart.cs
@@ -0,0 +1,37 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using UnixRStruct = RDotNet.Internals.Unix.RStart;
+
+namespace RDotNet.Internals.Windows
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct RStart
+ {
+ internal UnixRStruct Common;
+ public IntPtr rhome;
+ public IntPtr home;
+
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public blah1 ReadConsole;
+
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public blah2 WriteConsole;
+
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public blah3 CallBack;
+
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public blah4 ShowMessage;
+
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public blah5 YesNoCancel;
+
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public blah6 Busy;
+
+ public UiMode CharacterMode;
+
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public blah7 WriteConsoleEx;
+ }
+}
diff --git a/rdotnet/R.NET/Internals/Windows/UiMode.cs b/rdotnet/R.NET/Internals/Windows/UiMode.cs
new file mode 100644
index 0000000..4f4a9a1
--- /dev/null
+++ b/rdotnet/R.NET/Internals/Windows/UiMode.cs
@@ -0,0 +1,9 @@
+ïnamespace RDotNet.Internals.Windows
+{
+ public enum UiMode
+ {
+ RGui,
+ RTerminal,
+ LinkDll,
+ }
+}
diff --git a/rdotnet/R.NET/Internals/YesNoCancel.cs b/rdotnet/R.NET/Internals/YesNoCancel.cs
new file mode 100644
index 0000000..9f2ef21
--- /dev/null
+++ b/rdotnet/R.NET/Internals/YesNoCancel.cs
@@ -0,0 +1,23 @@
+ïnamespace RDotNet.Internals
+{
+ /// <summary>
+ /// User's decision.
+ /// </summary>
+ public enum YesNoCancel
+ {
+ /// <summary>
+ /// User agreed.
+ /// </summary>
+ Yes = 1,
+
+ /// <summary>
+ /// User disagreed.
+ /// </summary>
+ No = -1,
+
+ /// <summary>
+ /// User abandoned to answer.
+ /// </summary>
+ Cancel = 0,
+ }
+}
diff --git a/rdotnet/R.NET/Internals/sxpinfo.cs b/rdotnet/R.NET/Internals/sxpinfo.cs
new file mode 100644
index 0000000..fe7515a
--- /dev/null
+++ b/rdotnet/R.NET/Internals/sxpinfo.cs
@@ -0,0 +1,60 @@
+ïusing System.Runtime.InteropServices;
+
+namespace RDotNet.Internals
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct sxpinfo
+ {
+ private uint bits;
+
+ public SymbolicExpressionType type
+ {
+ get { return (SymbolicExpressionType)(this.bits & 31u); }
+ }
+
+ public uint obj
+ {
+ get { return ((this.bits & 32u) / 32); }
+ }
+
+ public uint named
+ {
+ get { return ((this.bits & 192u) / 64); }
+ }
+
+ public uint gp
+ {
+ get { return ((this.bits & 16776960u) / 256); }
+ }
+
+ public uint mark
+ {
+ get { return ((this.bits & 16777216u) / 16777216); }
+ }
+
+ public uint debug
+ {
+ get { return ((this.bits & 33554432u) / 33554432); }
+ }
+
+ public uint trace
+ {
+ get { return ((this.bits & 67108864u) / 67108864); }
+ }
+
+ public uint spare
+ {
+ get { return ((this.bits & 134217728u) / 134217728); }
+ }
+
+ public uint gcgen
+ {
+ get { return ((this.bits & 268435456u) / 268435456); }
+ }
+
+ public uint gccls
+ {
+ get { return ((this.bits & 3758096384u) / 536870912); }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Language.cs b/rdotnet/R.NET/Language.cs
new file mode 100644
index 0000000..795d70b
--- /dev/null
+++ b/rdotnet/R.NET/Language.cs
@@ -0,0 +1,38 @@
+ïusing System;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A language object.
+ /// </summary>
+ public class Language : SymbolicExpression
+ {
+ /// <summary>
+ /// Creates a language object.
+ /// </summary>
+ /// <param name="engine">The engine</param>
+ /// <param name="pointer">The pointer.</param>
+ protected internal Language(REngine engine, IntPtr pointer)
+ : base(engine, pointer)
+ {}
+
+ /// <summary>
+ /// Gets function calls.
+ /// </summary>
+ public Pairlist FunctionCall
+ {
+ get
+ {
+ int count = Engine.GetFunction<Rf_length>("Rf_length")(handle);
+ // count == 1 for empty call.
+ if (count < 2)
+ {
+ return null;
+ }
+ SEXPREC sexp = GetInternalStructure();
+ return new Pairlist(Engine, sexp.listsxp.cdrval);
+ }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/LogicalMatrix.cs b/rdotnet/R.NET/LogicalMatrix.cs
new file mode 100644
index 0000000..f13e0a9
--- /dev/null
+++ b/rdotnet/R.NET/LogicalMatrix.cs
@@ -0,0 +1,96 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A matrix of Boolean values.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class LogicalMatrix : Matrix<bool>
+ {
+ /// <summary>
+ /// Creates a new empty LogicalMatrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="rowCount">The row size.</param>
+ /// <param name="columnCount">The column size.</param>
+ /// <seealso cref="REngineExtension.CreateLogicalMatrix(REngine, int, int)"/>
+ public LogicalMatrix(REngine engine, int rowCount, int columnCount)
+ : base(engine, SymbolicExpressionType.LogicalVector, rowCount, columnCount)
+ {}
+
+ /// <summary>
+ /// Creates a new LogicalMatrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="matrix">The values.</param>
+ /// <seealso cref="REngineExtension.CreateLogicalMatrix(REngine, bool[,])"/>
+ public LogicalMatrix(REngine engine, bool[,] matrix)
+ : base(engine, SymbolicExpressionType.LogicalVector, matrix)
+ {}
+
+ /// <summary>
+ /// Creates a new instance for a Boolean matrix.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a Boolean matrix.</param>
+ protected internal LogicalMatrix(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="rowIndex">The zero-based rowIndex index of the element to get or set.</param>
+ /// <param name="columnIndex">The zero-based columnIndex index of the element to get or
set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override bool this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex < 0 || RowCount <= rowIndex)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex < 0 || ColumnCount <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(rowIndex, columnIndex);
+ int data = Marshal.ReadInt32(DataPointer, offset);
+ return Convert.ToBoolean(data);
+ }
+ }
+ set
+ {
+ if (rowIndex < 0 || RowCount <= rowIndex)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex < 0 || ColumnCount <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(rowIndex, columnIndex);
+ int data = Convert.ToInt32(value);
+ Marshal.WriteInt32(DataPointer, offset, data);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of an integer in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get { return sizeof(int); }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/LogicalVector.cs b/rdotnet/R.NET/LogicalVector.cs
new file mode 100644
index 0000000..3c4d6a9
--- /dev/null
+++ b/rdotnet/R.NET/LogicalVector.cs
@@ -0,0 +1,91 @@
+ïusing System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A collection of Boolean values.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class LogicalVector : Vector<bool>
+ {
+ /// <summary>
+ /// Creates a new empty LogicalVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="length">The length.</param>
+ /// <seealso cref="REngineExtension.CreateLogicalVector(REngine, int)"/>
+ public LogicalVector(REngine engine, int length)
+ : base(engine, SymbolicExpressionType.LogicalVector, length)
+ {}
+
+ /// <summary>
+ /// Creates a new LogicalVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="vector">The values.</param>
+ /// <seealso cref="REngineExtension.CreateLogicalVector(REngine, IEnumerable{bool})"/>
+ public LogicalVector(REngine engine, IEnumerable<bool> vector)
+ : base(engine, SymbolicExpressionType.LogicalVector, vector)
+ {}
+
+ /// <summary>
+ /// Creates a new instance for a Boolean vector.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a Boolean vector.</param>
+ protected internal LogicalVector(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index of the element to get or set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override bool this[int index]
+ {
+ get
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(index);
+ int data = Marshal.ReadInt32(DataPointer, offset);
+ return Convert.ToBoolean(data);
+ }
+ }
+ set
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(index);
+ int data = Convert.ToInt32(value);
+ Marshal.WriteInt32(DataPointer, offset, data);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of a Boolean value in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get
+ {
+ // Boolean is int internally.
+ return sizeof(int);
+ }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Matrix.cs b/rdotnet/R.NET/Matrix.cs
new file mode 100644
index 0000000..b54fca5
--- /dev/null
+++ b/rdotnet/R.NET/Matrix.cs
@@ -0,0 +1,280 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A matrix base.
+ /// </summary>
+ /// <typeparam name="T">The element type.</typeparam>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public abstract class Matrix<T> : SymbolicExpression
+ {
+ /// <summary>
+ /// Creates a new matrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="type">The element type.</param>
+ /// <param name="rowCount">The size of row.</param>
+ /// <param name="columnCount">The size of column.</param>
+ protected Matrix(REngine engine, SymbolicExpressionType type, int rowCount, int columnCount)
+ : base(engine, engine.GetFunction<Rf_allocMatrix>("Rf_allocMatrix")(type, rowCount,
columnCount))
+ {
+ if (rowCount <= 0)
+ {
+ throw new ArgumentOutOfRangeException("rowCount");
+ }
+ if (columnCount <= 0)
+ {
+ throw new ArgumentOutOfRangeException("columnCount");
+ }
+ var empty = new byte[rowCount * columnCount * DataSize];
+ Marshal.Copy(empty, 0, DataPointer, empty.Length);
+ }
+
+
+ /// <summary>
+ /// Creates a new matrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="type">The element type.</param>
+ /// <param name="matrix">The values.</param>
+ public Matrix(REngine engine, SymbolicExpressionType type, T[,] matrix)
+ : base(engine, engine.GetFunction<Rf_allocMatrix>("Rf_allocMatrix")(type,
matrix.GetLength(0), matrix.GetLength(1)))
+ {
+ int rowCount = RowCount;
+ int columnCount = ColumnCount;
+ for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
+ {
+ for (int columnIndex = 0; columnIndex < columnCount; columnIndex++)
+ {
+ this[rowIndex, columnIndex] = matrix[rowIndex, columnIndex];
+ }
+ }
+ }
+
+ /// <summary>
+ /// Creates a new instance for a matrix.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="coerced">The pointer to a matrix.</param>
+ protected Matrix(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="rowIndex">The zero-based row index of the element to get or set.</param>
+ /// <param name="columnIndex">The zero-based column index of the element to get or
set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public abstract T this[int rowIndex, int columnIndex] { get; set; }
+
+ /// <summary>
+ /// Gets or sets the element at the specified names.
+ /// </summary>
+ /// <param name="rowName">The row name of the element to get or set.</param>
+ /// <param name="columnName">The column name of the element to get or set.</param>
+ /// <returns>The element at the specified names.</returns>
+ public virtual T this[string rowName, string columnName]
+ {
+ get
+ {
+ if (rowName == null)
+ {
+ throw new ArgumentNullException("rowName");
+ }
+ if (columnName == null)
+ {
+ throw new ArgumentNullException("columnName");
+ }
+ string[] rowNames = RowNames;
+ if (rowNames == null)
+ {
+ throw new InvalidOperationException();
+ }
+ string[] columnNames = ColumnNames;
+ if (columnNames == null)
+ {
+ throw new InvalidOperationException();
+ }
+ int rowIndex = Array.IndexOf(rowNames, rowName);
+ int columnIndex = Array.IndexOf(columnNames, columnName);
+ return this[rowIndex, columnIndex];
+ }
+ set
+ {
+ if (rowName == null)
+ {
+ throw new ArgumentNullException("rowName");
+ }
+ if (columnName == null)
+ {
+ throw new ArgumentNullException("columnName");
+ }
+ string[] rowNames = RowNames;
+ if (rowNames == null)
+ {
+ throw new InvalidOperationException();
+ }
+ string[] columnNames = ColumnNames;
+ if (columnNames == null)
+ {
+ throw new InvalidOperationException();
+ }
+ int rowIndex = Array.IndexOf(rowNames, rowName);
+ int columnIndex = Array.IndexOf(columnNames, columnName);
+ this[rowIndex, columnIndex] = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the row size of elements.
+ /// </summary>
+ public int RowCount
+ {
+ get { return Engine.GetFunction<Rf_nrows>("Rf_nrows")(handle); }
+ }
+
+ /// <summary>
+ /// Gets the column size of elements.
+ /// </summary>
+ public int ColumnCount
+ {
+ get { return Engine.GetFunction<Rf_ncols>("Rf_ncols")(handle); }
+ }
+
+ /// <summary>
+ /// Gets the names of rows.
+ /// </summary>
+ public string[] RowNames
+ {
+ get
+ {
+ SymbolicExpression dimnamesSymbol =
Engine.GetPredefinedSymbol("R_DimNamesSymbol");
+ SymbolicExpression dimnames = GetAttribute(dimnamesSymbol);
+ if (dimnames == null)
+ {
+ return null;
+ }
+ CharacterVector rowNames = dimnames.AsList()[0].AsCharacter();
+ if (rowNames == null)
+ {
+ return null;
+ }
+
+ int length = rowNames.Length;
+ var result = new string[length];
+ rowNames.CopyTo(result, length);
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Gets the names of columns.
+ /// </summary>
+ public string[] ColumnNames
+ {
+ get
+ {
+ SymbolicExpression dimnamesSymbol =
Engine.GetPredefinedSymbol("R_DimNamesSymbol");
+ SymbolicExpression dimnames = GetAttribute(dimnamesSymbol);
+ if (dimnames == null)
+ {
+ return null;
+ }
+ CharacterVector columnNames = dimnames.AsList()[1].AsCharacter();
+ if (columnNames == null)
+ {
+ return null;
+ }
+
+ int length = columnNames.Length;
+ var result = new string[length];
+ columnNames.CopyTo(result, length);
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Gets the pointer for the first element.
+ /// </summary>
+ protected IntPtr DataPointer
+ {
+ get { return IntPtr.Add(handle, Marshal.SizeOf(typeof(VECTOR_SEXPREC))); }
+ }
+
+ /// <summary>
+ /// Gets the size of an element in byte.
+ /// </summary>
+ protected abstract int DataSize { get; }
+
+ /// <summary>
+ /// Gets the offset for the specified indexes.
+ /// </summary>
+ /// <param name="rowIndex">The index of row.</param>
+ /// <param name="columnIndex">The index of column.</param>
+ /// <returns>The offset.</returns>
+ protected int GetOffset(int rowIndex, int columnIndex)
+ {
+ return DataSize * (columnIndex * RowCount + rowIndex);
+ }
+
+ /// <summary>
+ /// Copies the elements to the specified array.
+ /// </summary>
+ /// <param name="destination">The destination array.</param>
+ /// <param name="rowCount">The row length to copy.</param>
+ /// <param name="columnCount">The column length to copy.</param>
+ /// <param name="sourceRowIndex">The first row index of the matrix.</param>
+ /// <param name="sourceColumnIndex">The first column index of the matrix.</param>
+ /// <param name="destinationRowIndex">The first row index of the destination array.</param>
+ /// <param name="destinationColumnIndex">The first column index of the destination
array.</param>
+ public void CopyTo(T[,] destination, int rowCount, int columnCount, int sourceRowIndex = 0,
int sourceColumnIndex = 0, int destinationRowIndex = 0, int destinationColumnIndex = 0)
+ {
+ if (destination == null)
+ {
+ throw new ArgumentNullException("destination");
+ }
+ if (rowCount < 0)
+ {
+ throw new IndexOutOfRangeException("rowCount");
+ }
+ if (columnCount < 0)
+ {
+ throw new IndexOutOfRangeException("columnCount");
+ }
+ if (sourceRowIndex < 0 || RowCount < sourceRowIndex + rowCount)
+ {
+ throw new IndexOutOfRangeException("sourceRowIndex");
+ }
+ if (sourceColumnIndex < 0 || ColumnCount < sourceColumnIndex + columnCount)
+ {
+ throw new IndexOutOfRangeException("sourceColumnIndex");
+ }
+ if (destinationRowIndex < 0 || destination.GetLength(0) < destinationRowIndex +
rowCount)
+ {
+ throw new IndexOutOfRangeException("destinationRowIndex");
+ }
+ if (destinationColumnIndex < 0 || destination.GetLength(1) < destinationColumnIndex +
columnCount)
+ {
+ throw new IndexOutOfRangeException("destinationColumnIndex");
+ }
+
+ while (--rowCount >= 0)
+ {
+ int currentSourceRowIndex = sourceRowIndex++;
+ int currentDestinationRowIndex = destinationRowIndex++;
+ int currentColumnCount = columnCount;
+ int currentSourceColumnIndex = sourceColumnIndex;
+ int currentDestinationColumnIndex = destinationColumnIndex;
+ while (--currentColumnCount >= 0)
+ {
+ destination[currentDestinationRowIndex,
currentDestinationColumnIndex++] = this[currentSourceRowIndex, currentSourceColumnIndex++];
+ }
+ }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/NumericMatrix.cs b/rdotnet/R.NET/NumericMatrix.cs
new file mode 100644
index 0000000..d273d4f
--- /dev/null
+++ b/rdotnet/R.NET/NumericMatrix.cs
@@ -0,0 +1,105 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A matrix of real numbers in double precision.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class NumericMatrix : Matrix<double>
+ {
+ /// <summary>
+ /// Creates a new empty NumericMatrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="rowCount">The row size.</param>
+ /// <param name="columnCount">The column size.</param>
+ /// <seealso cref="REngineExtension.CreateNumericMatrix(REngine, int, int)"/>
+ public NumericMatrix(REngine engine, int rowCount, int columnCount)
+ : base(engine, SymbolicExpressionType.NumericVector, rowCount, columnCount)
+ {}
+
+ /// <summary>
+ /// Creates a new NumericMatrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="matrix">The values.</param>
+ /// <seealso cref="REngineExtension.CreateNumericMatrix(REngine, double[,])"/>
+ public NumericMatrix(REngine engine, double[,] matrix)
+ : base(engine, SymbolicExpressionType.NumericVector, matrix)
+ {}
+
+ /// <summary>
+ /// Creates a new instance for a numeric matrix.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a numeric matrix.</param>
+ protected internal NumericMatrix(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="rowIndex">The zero-based rowIndex index of the element to get or set.</param>
+ /// <param name="columnIndex">The zero-based columnIndex index of the element to get or
set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override double this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex < 0 || RowCount <= rowIndex)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex < 0 || ColumnCount <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ using (new ProtectedPointer(this))
+ {
+ var data = new byte[DataSize];
+ IntPtr pointer = DataPointer;
+ int offset = GetOffset(rowIndex, columnIndex);
+ for (int byteIndex = 0; byteIndex < data.Length; byteIndex++)
+ {
+ data[byteIndex] = Marshal.ReadByte(pointer, offset +
byteIndex);
+ }
+ return BitConverter.ToDouble(data, 0);
+ }
+ }
+ set
+ {
+ if (rowIndex < 0 || RowCount <= rowIndex)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex < 0 || ColumnCount <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ using (new ProtectedPointer(this))
+ {
+ byte[] data = BitConverter.GetBytes(value);
+ IntPtr pointer = DataPointer;
+ int offset = GetOffset(rowIndex, columnIndex);
+ for (int byteIndex = 0; byteIndex < data.Length; byteIndex++)
+ {
+ Marshal.WriteByte(pointer, offset + byteIndex,
data[byteIndex]);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of a real number in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get { return sizeof(double); }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/NumericVector.cs b/rdotnet/R.NET/NumericVector.cs
new file mode 100644
index 0000000..94de933
--- /dev/null
+++ b/rdotnet/R.NET/NumericVector.cs
@@ -0,0 +1,133 @@
+ïusing System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A collection of real numbers in double precision.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class NumericVector : Vector<double>
+ {
+ /// <summary>
+ /// Creates a new empty NumericVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="length">The length.</param>
+ /// <seealso cref="REngineExtension.CreateNumericVector(REngine, int)"/>
+ public NumericVector(REngine engine, int length)
+ : base(engine, SymbolicExpressionType.NumericVector, length)
+ {}
+
+ /// <summary>
+ /// Creates a new NumericVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="vector">The values.</param>
+ /// <seealso cref="REngineExtension.CreateNumericVector(REngine, IEnumerable{double})"/>
+ public NumericVector(REngine engine, IEnumerable<double> vector)
+ : base(engine, SymbolicExpressionType.NumericVector, vector)
+ {}
+
+ /// <summary>
+ /// Creates a new NumericVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="vector">The values.</param>
+ /// <seealso cref="REngineExtension.CreateNumericVector(REngine, double[])"/>
+ public NumericVector(REngine engine, double[] vector)
+ : base(engine, SymbolicExpressionType.NumericVector, vector.Length)
+ {
+ Marshal.Copy(vector, 0, DataPointer, vector.Length);
+ }
+
+ /// <summary>
+ /// Creates a new instance for a numeric vector.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a numeric vector.</param>
+ protected internal NumericVector(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index of the element to get or set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override double this[int index]
+ {
+ get
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ var data = new double[1];
+ int offset = GetOffset(index);
+ IntPtr pointer = IntPtr.Add(DataPointer, offset);
+ Marshal.Copy(pointer, data, 0, data.Length);
+ return data[0];
+ }
+ }
+ set
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ var data = new[] { value };
+ int offset = GetOffset(index);
+ IntPtr pointer = IntPtr.Add(DataPointer, offset);
+ Marshal.Copy(data, 0, pointer, data.Length);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of a real number in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get { return sizeof(double); }
+ }
+
+ /// <summary>
+ /// Copies the elements to the specified array.
+ /// </summary>
+ /// <param name="destination">The destination array.</param>
+ /// <param name="length">The length to copy.</param>
+ /// <param name="sourceIndex">The first index of the vector.</param>
+ /// <param name="destinationIndex">The first index of the destination array.</param>
+ public new void CopyTo(double[] destination, int length, int sourceIndex = 0, int
destinationIndex = 0)
+ {
+ if (destination == null)
+ {
+ throw new ArgumentNullException("destination");
+ }
+ if (length < 0)
+ {
+ throw new IndexOutOfRangeException("length");
+ }
+ if (sourceIndex < 0 || Length < sourceIndex + length)
+ {
+ throw new IndexOutOfRangeException("sourceIndex");
+ }
+ if (destinationIndex < 0 || destination.Length < destinationIndex + length)
+ {
+ throw new IndexOutOfRangeException("destinationIndex");
+ }
+
+ int offset = GetOffset(sourceIndex);
+ IntPtr pointer = IntPtr.Add(DataPointer, offset);
+ Marshal.Copy(pointer, destination, destinationIndex, length);
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Pairlist.cs b/rdotnet/R.NET/Pairlist.cs
new file mode 100644
index 0000000..972b223
--- /dev/null
+++ b/rdotnet/R.NET/Pairlist.cs
@@ -0,0 +1,51 @@
+ïusing System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A pairlist.
+ /// </summary>
+ public class Pairlist : SymbolicExpression, IEnumerable<Symbol>
+ {
+ /// <summary>
+ /// Creates a pairlist.
+ /// </summary>
+ /// <param name="engine">The engine</param>
+ /// <param name="pointer">The pointer.</param>
+ protected internal Pairlist(REngine engine, IntPtr pointer)
+ : base(engine, pointer)
+ {}
+
+ /// <summary>
+ /// Gets the number of nodes.
+ /// </summary>
+ public int Count
+ {
+ get { return Engine.GetFunction<Rf_length>("Rf_length")(handle); }
+ }
+
+ #region IEnumerable<Symbol> Members
+
+ public IEnumerator<Symbol> GetEnumerator()
+ {
+ if (Count != 0)
+ {
+ for (SEXPREC sexp = GetInternalStructure(); sexp.sxpinfo.type !=
SymbolicExpressionType.Null; sexp = (SEXPREC)Marshal.PtrToStructure(sexp.listsxp.cdrval, typeof(SEXPREC)))
+ {
+ yield return new Symbol(Engine, sexp.listsxp.tagval);
+ }
+ }
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ #endregion
+ }
+}
diff --git a/rdotnet/R.NET/ParseException.cs b/rdotnet/R.NET/ParseException.cs
new file mode 100644
index 0000000..29ba066
--- /dev/null
+++ b/rdotnet/R.NET/ParseException.cs
@@ -0,0 +1,70 @@
+ïusing System;
+using System.Runtime.Serialization;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// Thrown when an engine comes to an error.
+ /// </summary>
+ [Serializable]
+ public class ParseException : ApplicationException
+ {
+ private const string StatusFieldName = "status";
+
+ private const string ErrorStatementFieldName = "errorStatement";
+ private readonly string errorStatement;
+ private readonly ParseStatus status;
+
+ /// <summary>
+ /// Creates a new instance.
+ /// </summary>
+ public ParseException()
+ {
+ // This does not internally occur. See Parse.h in R_HOME/include/R_ext/Parse.h
+ this.status = ParseStatus.Null;
+ this.errorStatement = null;
+ }
+
+ /// <summary>
+ /// Creates a new instance with the specified error.
+ /// </summary>
+ /// <param name="status">The error.</param>
+ /// <param name="errorStatement">The error statement.</param>
+ public ParseException(ParseStatus status, string errorStatement)
+ {
+ this.status = status;
+ this.errorStatement = errorStatement;
+ }
+
+ protected ParseException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ this.status = (ParseStatus)info.GetValue(StatusFieldName, typeof(ParseStatus));
+ this.errorStatement = info.GetString(ErrorStatementFieldName);
+ }
+
+ /// <summary>
+ /// The error.
+ /// </summary>
+ public ParseStatus Status
+ {
+ get { return this.status; }
+ }
+
+ /// <summary>
+ /// The statement caused the error.
+ /// </summary>
+ public string ErrorStatement
+ {
+ get { return this.errorStatement; }
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue(StatusFieldName, this.status);
+ info.AddValue(ErrorStatementFieldName, this.errorStatement);
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Properties/AssemblyInfo.cs b/rdotnet/R.NET/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..2a958f5
--- /dev/null
+++ b/rdotnet/R.NET/Properties/AssemblyInfo.cs
@@ -0,0 +1,39 @@
+ïusing System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly : AssemblyTitle("R.NET")]
+[assembly : AssemblyDescription("Collaboration of .NET Framework with R statistical computing")]
+[assembly : AssemblyConfiguration("")]
+[assembly : AssemblyCompany("RecycleBin")]
+[assembly : AssemblyProduct("R.NET")]
+[assembly : AssemblyCopyright("Copyright  RecycleBin 2011")]
+[assembly : AssemblyTrademark("")]
+[assembly : AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly : ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly : Guid("9ecd1b81-67cd-417a-8b4d-77847c3353d4")]
+
+// DllVersion information for an assembly consists of the following four values:
+//
+// Major DllVersion
+// Minor DllVersion
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+
+[assembly : AssemblyVersion("1.5.0.0")]
+[assembly : AssemblyFileVersion("1.5.0.0")]
diff --git a/rdotnet/R.NET/ProtectedPointer.cs b/rdotnet/R.NET/ProtectedPointer.cs
new file mode 100644
index 0000000..b8ddc29
--- /dev/null
+++ b/rdotnet/R.NET/ProtectedPointer.cs
@@ -0,0 +1,43 @@
+ïusing System;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ internal class ProtectedPointer : IDisposable
+ {
+ private readonly REngine engine;
+ private readonly IntPtr sexp;
+
+ public ProtectedPointer(REngine engine, IntPtr sexp)
+ {
+ this.sexp = sexp;
+ this.engine = engine;
+
+ engine.GetFunction<Rf_protect>("Rf_protect")(this.sexp);
+ }
+
+ public ProtectedPointer(SymbolicExpression sexp)
+ {
+ this.sexp = sexp.DangerousGetHandle();
+ this.engine = sexp.Engine;
+
+ this.engine.GetFunction<Rf_protect>("Rf_protect")(this.sexp);
+ }
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ this.engine.GetFunction<Rf_unprotect_ptr>("Rf_unprotect_ptr")(this.sexp);
+ }
+
+ #endregion
+
+ public static implicit operator IntPtr(ProtectedPointer p)
+ {
+ return p.sexp;
+ }
+ }
+}
diff --git a/rdotnet/R.NET/RDotNet.csproj b/rdotnet/R.NET/RDotNet.csproj
new file mode 100644
index 0000000..4e18f32
--- /dev/null
+++ b/rdotnet/R.NET/RDotNet.csproj
@@ -0,0 +1,137 @@
+ï<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{0923E1A0-2032-4997-AB73-49E42C4034A9}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>RDotNet</RootNamespace>
+ <AssemblyName>RDotNet</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>TRACE;DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <DocumentationFile>bin\Debug\RDotNet.xml</DocumentationFile>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>none</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DocumentationFile>bin\Release\RDotNet.xml</DocumentationFile>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SignAssembly>true</SignAssembly>
+ </PropertyGroup>
+ <PropertyGroup>
+ <DelaySign>true</DelaySign>
+ </PropertyGroup>
+ <PropertyGroup>
+ <AssemblyOriginatorKeyFile>..\RecycleBin.snk.pub</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Numerics" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Closure.cs" />
+ <Compile Include="ComplexVector.cs" />
+ <Compile Include="CharacterMatrix.cs" />
+ <Compile Include="ComplexMatrix.cs" />
+ <Compile Include="BuiltinFunction.cs" />
+ <Compile Include="Devices\CharacterDeviceAdapter.cs" />
+ <Compile Include="Devices\ConsoleDevice.cs" />
+ <Compile Include="Devices\NullCharacterDevice.cs" />
+ <Compile Include="Devices\ICharacterDevice.cs" />
+ <Compile Include="Internals\Delegates.cs" />
+ <Compile Include="Internals\OutputMode.cs" />
+ <Compile Include="Internals\Unix\RStart.cs" />
+ <Compile Include="Internals\ConsoleOutputType.cs" />
+ <Compile Include="Internals\BusyType.cs" />
+ <Compile Include="Internals\SaveActions.cs" />
+ <Compile Include="Internals\Unix\Delegates.cs" />
+ <Compile Include="Internals\Windows\Delegates.cs" />
+ <Compile Include="Internals\Windows\RStart.cs" />
+ <Compile Include="Internals\Windows\UiMode.cs" />
+ <Compile Include="Internals\YesNoCancel.cs" />
+ <Compile Include="SpecialFunction.cs" />
+ <Compile Include="Environment.cs" />
+ <Compile Include="Expression.cs" />
+ <Compile Include="ExpressionVector.cs" />
+ <Compile Include="DataFrame.cs" />
+ <Compile Include="DataFrameRow.cs" />
+ <Compile Include="DynamicVector.cs" />
+ <Compile Include="Dynamic\DataFrameDynamicMeta.cs" />
+ <Compile Include="Dynamic\SymbolicExpressionDynamicMeta.cs" />
+ <Compile Include="Dynamic\ListDynamicMeta.cs" />
+ <Compile Include="Function.cs" />
+ <Compile Include="GenericVector.cs" />
+ <Compile Include="Language.cs" />
+ <Compile Include="LogicalMatrix.cs" />
+ <Compile Include="Pairlist.cs" />
+ <Compile Include="RawMatrix.cs" />
+ <Compile Include="NumericMatrix.cs" />
+ <Compile Include="IntegerMatrix.cs" />
+ <Compile Include="Matrix.cs" />
+ <Compile Include="InternalString.cs" />
+ <Compile Include="Internals\SEXPREC_HEADER.cs" />
+ <Compile Include="RawVector.cs" />
+ <Compile Include="Internals\ParseStatus.cs" />
+ <Compile Include="NumericVector.cs" />
+ <Compile Include="IntegerVector.cs" />
+ <Compile Include="Internals\VECTOR_SEXPREC.cs" />
+ <Compile Include="ParseException.cs" />
+ <Compile Include="ProtectedPointer.cs" />
+ <Compile Include="REngineExtension.cs" />
+ <Compile Include="StartupParameter.cs" />
+ <Compile Include="Symbol.cs" />
+ <Compile Include="SymbolicExpression.cs" />
+ <Compile Include="Internals\SEXPREC.cs" />
+ <Compile Include="Internals\SymbolicExpressionType.cs" />
+ <Compile Include="Internals\sxpinfo.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="REngine.cs" />
+ <Compile Include="SymbolicExpressionExtension.cs" />
+ <Compile Include="Utility.cs" />
+ <Compile Include="Vector.cs" />
+ <Compile Include="LogicalVector.cs" />
+ <Compile Include="CharacterVector.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\RDotNet.NativeLibrary\RDotNet.NativeLibrary.csproj">
+ <Project>{2A089A59-0F22-4484-B442-0FE8BDA10879}</Project>
+ <Name>RDotNet.NativeLibrary</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>
+ </PreBuildEvent>
+ </PropertyGroup>
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
diff --git a/rdotnet/R.NET/REngine.cs b/rdotnet/R.NET/REngine.cs
new file mode 100644
index 0000000..b97c66a
--- /dev/null
+++ b/rdotnet/R.NET/REngine.cs
@@ -0,0 +1,529 @@
+ïusing System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using System.Text;
+using RDotNet.Devices;
+using RDotNet.Internals;
+using RDotNet.NativeLibrary;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// REngine handles R environment through evaluation of R statement.
+ /// </summary>
+ /// <example>This example generates and outputs five random numbers from standard normal distribution.
+ /// <code>
+ /// Environment.SetEnvironmentVariable("PATH", @"C:\Program Files\R\R-2.12.0\bin\i386");
+ /// using (REngine engine = REngine.CreateInstance("RDotNet"))
+ /// {
+ /// engine.Initialize();
+ /// NumericVector random = engine.Evaluate("rnorm(5, 0, 1)").AsNumeric();
+ /// foreach (double r in random)
+ /// {
+ /// Console.Write(r + " ");
+ /// }
+ /// }
+ /// </code>
+ /// </example>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class REngine : UnmanagedDll
+ {
+ private static readonly ICharacterDevice DefaultDevice = new ConsoleDevice();
+ private static readonly Dictionary<string, REngine> instances = new Dictionary<string,
REngine>();
+
+ private readonly string id;
+ private CharacterDeviceAdapter adapter;
+ private bool isRunning;
+ private StartupParameter parameter;
+
+ private REngine(string id, string dll)
+ : base(dll)
+ {
+ this.id = id;
+ this.isRunning = false;
+ }
+
+ /// <summary>
+ /// Gets whether this instance is running.
+ /// </summary>
+ public bool IsRunning
+ {
+ get { return this.isRunning; }
+ }
+
+ /// <summary>
+ /// Gets the version of R.DLL.
+ /// </summary>
+ public string DllVersion
+ {
+ get
+ {
+ // As R's version definitions are defined in #define preprocessor,
+ // C# cannot access them dynamically.
+ // But, on Win32 platform, we can get the version string via getDLLVersion
function.
+ if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+ {
+ throw new NotImplementedException();
+ }
+ var getVersion = GetFunction<_getDLLVersion>("getDLLVersion");
+ return Marshal.PtrToStringAnsi(getVersion());
+ }
+ }
+
+ /// <summary>
+ /// Gets the ID of this instance.
+ /// </summary>
+ public string ID
+ {
+ get { return this.id; }
+ }
+
+ /// <summary>
+ /// Gets the global environment.
+ /// </summary>
+ public REnvironment GlobalEnvironment
+ {
+ get
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ return GetPredefinedSymbol("R_GlobalEnv").AsEnvironment();
+ }
+ }
+
+ /// <summary>
+ /// Gets the root environment.
+ /// </summary>
+ public REnvironment EmptyEnvironment
+ {
+ get
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ return GetPredefinedSymbol("R_EmptyEnv").AsEnvironment();
+ }
+ }
+
+ /// <summary>
+ /// Gets the base environment.
+ /// </summary>
+ public REnvironment BaseNamespace
+ {
+ get
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ return GetPredefinedSymbol("R_BaseNamespace").AsEnvironment();
+ }
+ }
+
+ /// <summary>
+ /// Gets the <c>NULL</c> value.
+ /// </summary>
+ public SymbolicExpression NilValue
+ {
+ get
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ return GetPredefinedSymbol("R_NilValue");
+ }
+ }
+
+ /// <summary>
+ /// Gets the unbound value.
+ /// </summary>
+ public SymbolicExpression UnboundValue
+ {
+ get
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ return GetPredefinedSymbol("R_UnboundValue");
+ }
+ }
+
+ /// <summary>
+ /// Creates a new instance that handles R.DLL.
+ /// </summary>
+ /// <param name="id">ID.</param>
+ /// <param name="dll">The core dll of R.</param>
+ /// <returns>The engine.</returns>
+ public static REngine CreateInstance(string id, string dll = null)
+ {
+ if (id == null)
+ {
+ throw new ArgumentNullException("id", "Empty ID is not allowed.");
+ }
+ if (id == string.Empty)
+ {
+ throw new ArgumentException("Empty ID is not allowed.", "id");
+ }
+ if (instances.ContainsKey(id))
+ {
+ throw new ArgumentException();
+ }
+ if (dll == null)
+ {
+ switch (NativeUtility.GetPlatform())
+ {
+ case PlatformID.Win32NT:
+ dll = "R.dll";
+ break;
+ case PlatformID.MacOSX:
+ dll = "libR.dylib";
+ break;
+ case PlatformID.Unix:
+ dll = "libR.so";
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+ var engine = new REngine(id, dll);
+ instances.Add(id, engine);
+ return engine;
+ }
+
+ /// <summary>
+ /// Gets an instance specified in the given ID.
+ /// </summary>
+ /// <param name="id">ID.</param>
+ /// <returns>The engine.</returns>
+ public static REngine GetInstanceFromID(string id)
+ {
+ REngine engine;
+ instances.TryGetValue(id, out engine);
+ return engine;
+ }
+
+ /// <summary>
+ /// Initializes R process.
+ /// </summary>
+ /// <param name="parameter">The startup parameter.</param>
+ /// <param name="device">The IO device.</param>
+ public void Initialize(StartupParameter parameter = null, ICharacterDevice device = null)
+ {
+ this.parameter = parameter ?? new StartupParameter();
+ this.adapter = new CharacterDeviceAdapter(device ?? DefaultDevice);
+ GetFunction<R_setStartTime>("R_setStartTime")();
+ GetFunction<Rf_initialize_R>("Rf_initialize_R")(1, new[] { ID });
+ this.adapter.Install(this, this.parameter);
+ switch (Environment.OSVersion.Platform)
+ {
+ case PlatformID.Win32NT:
+ GetFunction<R_SetParams_Windows>("R_SetParams")(ref
this.parameter.start);
+ break;
+ case PlatformID.MacOSX:
+ case PlatformID.Unix:
+ GetFunction<R_SetParams_Unix>("R_SetParams")(ref
this.parameter.start.Common);
+ break;
+ }
+ GetFunction<setup_Rmainloop>("setup_Rmainloop")();
+ this.isRunning = true;
+ }
+
+ /// <summary>
+ /// Forces garbage collection.
+ /// </summary>
+ public void ForceGarbageCollection()
+ {
+ GetFunction<R_gc>("R_gc")();
+ }
+
+ /// <summary>
+ /// Gets a symbol defined in the global environment.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <returns>The symbol.</returns>
+ public SymbolicExpression GetSymbol(string name)
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ return GlobalEnvironment.GetSymbol(name);
+ }
+
+ /// <summary>
+ /// Gets a symbol defined in the global environment.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="environment">The environment. If <c>null</c> is passed, <see
cref="GlobalEnvironment"/> is used.</param>
+ /// <returns>The symbol.</returns>
+ public SymbolicExpression GetSymbol(string name, REnvironment environment)
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ if (environment == null)
+ {
+ environment = GlobalEnvironment;
+ }
+ return environment.GetSymbol(name);
+ }
+
+ /// <summary>
+ /// Defines a symbol in the global environment.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="expression">The symbol.</param>
+ public void SetSymbol(string name, SymbolicExpression expression)
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ GlobalEnvironment.SetSymbol(name, expression);
+ }
+
+ /// <summary>
+ /// Defines a symbol in the specified environment.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="expression">The symbol.</param>
+ /// <param name="environment">The environment. If <c>null</c> is passed, <see
cref="GlobalEnvironment"/> is used.</param>
+ public void SetSymbol(string name, SymbolicExpression expression, REnvironment environment)
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ if (environment == null)
+ {
+ environment = GlobalEnvironment;
+ }
+ environment.SetSymbol(name, expression);
+ }
+
+ /// <summary>
+ /// Evaluates a statement in the given string.
+ /// </summary>
+ /// <param name="statement">The statement.</param>
+ /// <returns>Last evaluation.</returns>
+ public SymbolicExpression Evaluate(string statement)
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ return Defer(statement).LastOrDefault();
+ }
+
+ /// <summary>
+ /// Evaluates a statement in the given stream.
+ /// </summary>
+ /// <param name="stream">The stream.</param>
+ /// <returns>Last evaluation.</returns>
+ public SymbolicExpression Evaluate(Stream stream)
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ return Defer(stream).LastOrDefault();
+ }
+
+ /// <summary>
+ /// Evaluates a statement in the given string.
+ /// </summary>
+ /// <param name="statement">The statement.</param>
+ /// <returns>Each evaluation.</returns>
+ private IEnumerable<SymbolicExpression> Defer(string statement)
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ if (statement == null)
+ {
+ throw new ArgumentNullException();
+ }
+
+ using (TextReader reader = new StringReader(statement))
+ {
+ var incompleteStatement = new StringBuilder();
+ string line;
+ while ((line = reader.ReadLine()) != null)
+ {
+ foreach (string segment in Segment(line))
+ {
+ SymbolicExpression result = Parse(segment,
incompleteStatement);
+ if (result != null)
+ {
+ yield return result;
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Evaluates a statement in the given stream.
+ /// </summary>
+ /// <param name="stream">The stream.</param>
+ /// <returns>Each evaluation.</returns>
+ public IEnumerable<SymbolicExpression> Defer(Stream stream)
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ if (stream == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!stream.CanRead)
+ {
+ throw new ArgumentException();
+ }
+
+ using (TextReader reader = new StreamReader(stream))
+ {
+ var incompleteStatement = new StringBuilder();
+ string line;
+ while ((line = reader.ReadLine()) != null)
+ {
+ foreach (string segment in Segment(line))
+ {
+ SymbolicExpression result = Parse(segment,
incompleteStatement);
+ if (result != null)
+ {
+ yield return result;
+ }
+ }
+ }
+ }
+ }
+
+ private static IEnumerable<string> Segment(string line)
+ {
+ string[] segments = line.Split(';');
+ for (int index = 0; index < segments.Length; index++)
+ {
+ if (index == segments.Length - 1)
+ {
+ if (segments[index] != string.Empty)
+ {
+ yield return segments[index];
+ }
+ }
+ else
+ {
+ yield return segments[index] + ";";
+ }
+ }
+ }
+
+ private SymbolicExpression Parse(string statement, StringBuilder incompleteStatement)
+ {
+ incompleteStatement.Append(statement);
+ IntPtr s = GetFunction<Rf_mkString>("Rf_mkString")(incompleteStatement.ToString());
+
+ using (new ProtectedPointer(this, s))
+ {
+ ParseStatus status;
+ var vector = new ExpressionVector(this,
GetFunction<R_ParseVector>("R_ParseVector")(s, -1, out status, NilValue.DangerousGetHandle()));
+ if (vector.Length == 0)
+ {
+ return null;
+ }
+
+ switch (status)
+ {
+ case ParseStatus.OK:
+ incompleteStatement.Clear();
+ using (new ProtectedPointer(vector))
+ {
+ SymbolicExpression result;
+ if (!vector.First().TryEvaluate(GlobalEnvironment,
out result))
+ {
+ throw new ParseException();
+ }
+ return result;
+ }
+ case ParseStatus.Incomplete:
+ return null;
+ default:
+ string errorStatement = incompleteStatement.ToString();
+ incompleteStatement.Clear();
+ throw new ParseException(status, errorStatement);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets the command line arguments.
+ /// </summary>
+ /// <param name="args">The arguments.</param>
+ public void SetCommandLineArguments(string[] args)
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ string[] newArgs = Utility.AddFirst(ID, args);
+
GetFunction<R_set_command_line_arguments>("R_set_command_line_arguments")(newArgs.Length, newArgs);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ this.isRunning = false;
+ instances.Remove(ID);
+ if (disposing)
+ {
+ GetFunction<Rf_endEmbeddedR>("Rf_endEmbeddedR")(0);
+ }
+ if (this.adapter != null)
+ {
+ this.adapter.Dispose();
+ this.adapter = null;
+ }
+ GC.KeepAlive(this.parameter);
+ base.Dispose(disposing);
+ }
+
+ /// <summary>
+ /// Gets the predefined symbol with the specified name.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <returns>The symbol.</returns>
+ public SymbolicExpression GetPredefinedSymbol(string name)
+ {
+ if (!IsRunning)
+ {
+ throw new InvalidOperationException();
+ }
+ try
+ {
+ IntPtr pointer = DangerousGetHandle(name);
+ return new SymbolicExpression(this, Marshal.ReadIntPtr(pointer));
+ }
+ catch (Exception ex)
+ {
+ throw new ArgumentException(null, ex);
+ }
+ }
+
+ #region Nested type: _getDLLVersion
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate IntPtr _getDLLVersion();
+
+ #endregion
+ }
+}
diff --git a/rdotnet/R.NET/REngineExtension.cs b/rdotnet/R.NET/REngineExtension.cs
new file mode 100644
index 0000000..cdeae31
--- /dev/null
+++ b/rdotnet/R.NET/REngineExtension.cs
@@ -0,0 +1,474 @@
+using System;
+using System.Collections.Generic;
+using System.Numerics;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// Provides extension methods for <see cref="REngine"/>.
+ /// </summary>
+ public static class REngineExtension
+ {
+ /// <summary>
+ /// Creates a new empty CharacterVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="length">The length.</param>
+ /// <returns>The new vector.</returns>
+ public static CharacterVector CreateCharacterVector(this REngine engine, int length)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new CharacterVector(engine, length);
+ }
+
+ /// <summary>
+ /// Creates a new empty ComplexVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="length">The length.</param>
+ /// <returns>The new vector.</returns>
+ public static ComplexVector CreateComplexVector(this REngine engine, int length)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new ComplexVector(engine, length);
+ }
+
+ /// <summary>
+ /// Creates a new empty IntegerVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="length">The length.</param>
+ /// <returns>The new vector.</returns>
+ public static IntegerVector CreateIntegerVector(this REngine engine, int length)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new IntegerVector(engine, length);
+ }
+
+ /// <summary>
+ /// Creates a new empty LogicalVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="length">The length.</param>
+ /// <returns>The new vector.</returns>
+ public static LogicalVector CreateLogicalVector(this REngine engine, int length)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new LogicalVector(engine, length);
+ }
+
+ /// <summary>
+ /// Creates a new empty NumericVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="length">The length.</param>
+ /// <returns>The new vector.</returns>
+ public static NumericVector CreateNumericVector(this REngine engine, int length)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new NumericVector(engine, length);
+ }
+
+ /// <summary>
+ /// Creates a new empty RawVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="length">The length.</param>
+ /// <returns>The new vector.</returns>
+ public static RawVector CreateRawVector(this REngine engine, int length)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new RawVector(engine, length);
+ }
+
+ /// <summary>
+ /// Creates a new CharacterVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="vector">The values.</param>
+ /// <returns>The new vector.</returns>
+ public static CharacterVector CreateCharacterVector(this REngine engine, IEnumerable<string>
vector)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new CharacterVector(engine, vector);
+ }
+
+ /// <summary>
+ /// Creates a new ComplexVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="vector">The values.</param>
+ /// <returns>The new vector.</returns>
+ public static ComplexVector CreateComplexVector(this REngine engine, IEnumerable<Complex>
vector)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new ComplexVector(engine, vector);
+ }
+
+ /// <summary>
+ /// Creates a new IntegerVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="vector">The values.</param>
+ /// <returns>The new vector.</returns>
+ public static IntegerVector CreateIntegerVector(this REngine engine, IEnumerable<int> vector)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new IntegerVector(engine, vector);
+ }
+
+ /// <summary>
+ /// Creates a new LogicalVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="vector">The values.</param>
+ /// <returns>The new vector.</returns>
+ public static LogicalVector CreateLogicalVector(this REngine engine, IEnumerable<bool> vector)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new LogicalVector(engine, vector);
+ }
+
+ /// <summary>
+ /// Creates a new NumericVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="vector">The values.</param>
+ /// <returns>The new vector.</returns>
+ public static NumericVector CreateNumericVector(this REngine engine, IEnumerable<double>
vector)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new NumericVector(engine, vector);
+ }
+
+ /// <summary>
+ /// Creates a new RawVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="vector">The values.</param>
+ /// <returns>The new vector.</returns>
+ public static RawVector CreateRawVector(this REngine engine, IEnumerable<byte> vector)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new RawVector(engine, vector);
+ }
+
+ /// <summary>
+ /// Creates a new empty CharacterMatrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="rowCount">The row size.</param>
+ /// <param name="columnCount">The column size.</param>
+ /// <returns>The new matrix.</returns>
+ public static CharacterMatrix CreateCharacterMatrix(this REngine engine, int rowCount, int
columnCount)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new CharacterMatrix(engine, rowCount, columnCount);
+ }
+
+ /// <summary>
+ /// Creates a new empty ComplexMatrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="rowCount">The row size.</param>
+ /// <param name="columnCount">The column size.</param>
+ /// <returns>The new matrix.</returns>
+ public static ComplexMatrix CreateComplexMatrix(this REngine engine, int rowCount, int
columnCount)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new ComplexMatrix(engine, rowCount, columnCount);
+ }
+
+ /// <summary>
+ /// Creates a new empty IntegerMatrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="rowCount">The row size.</param>
+ /// <param name="columnCount">The column size.</param>
+ /// <returns>The new matrix.</returns>
+ public static IntegerMatrix CreateIntegerMatrix(this REngine engine, int rowCount, int
columnCount)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new IntegerMatrix(engine, rowCount, columnCount);
+ }
+
+ /// <summary>
+ /// Creates a new empty LogicalMatrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="rowCount">The row size.</param>
+ /// <param name="columnCount">The column size.</param>
+ /// <returns>The new matrix.</returns>
+ public static LogicalMatrix CreateLogicalMatrix(this REngine engine, int rowCount, int
columnCount)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new LogicalMatrix(engine, rowCount, columnCount);
+ }
+
+ /// <summary>
+ /// Creates a new empty NumericMatrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="rowCount">The row size.</param>
+ /// <param name="columnCount">The column size.</param>
+ /// <returns>The new matrix.</returns>
+ public static NumericMatrix CreateNumericMatrix(this REngine engine, int rowCount, int
columnCount)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new NumericMatrix(engine, rowCount, columnCount);
+ }
+
+ /// <summary>
+ /// Creates a new empty RawMatrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="rowCount">The row size.</param>
+ /// <param name="columnCount">The column size.</param>
+ /// <returns>The new matrix.</returns>
+ public static RawMatrix CreateRawMatrix(this REngine engine, int rowCount, int columnCount)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new RawMatrix(engine, rowCount, columnCount);
+ }
+
+ /// <summary>
+ /// Creates a new CharacterMatrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="matrix">The values.</param>
+ /// <returns>The new matrix.</returns>
+ public static CharacterMatrix CreateCharacterMatrix(this REngine engine, string[,] matrix)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new CharacterMatrix(engine, matrix);
+ }
+
+ /// <summary>
+ /// Creates a new ComplexMatrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="matrix">The values.</param>
+ /// <returns>The new matrix.</returns>
+ public static ComplexMatrix CreateComplexMatrix(this REngine engine, Complex[,] matrix)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new ComplexMatrix(engine, matrix);
+ }
+
+ /// <summary>
+ /// Creates a new IntegerMatrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="matrix">The values.</param>
+ /// <returns>The new matrix.</returns>
+ public static IntegerMatrix CreateIntegerMatrix(this REngine engine, int[,] matrix)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new IntegerMatrix(engine, matrix);
+ }
+
+ /// <summary>
+ /// Creates a new LogicalMatrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="matrix">The values.</param>
+ /// <returns>The new matrix.</returns>
+ public static LogicalMatrix CreateLogicalMatrix(this REngine engine, bool[,] matrix)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new LogicalMatrix(engine, matrix);
+ }
+
+ /// <summary>
+ /// Creates a new NumericMatrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="matrix">The values.</param>
+ /// <returns>The new matrix.</returns>
+ public static NumericMatrix CreateNumericMatrix(this REngine engine, double[,] matrix)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new NumericMatrix(engine, matrix);
+ }
+
+ /// <summary>
+ /// Creates a new RawMatrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="matrix">The values.</param>
+ /// <returns>The new matrix.</returns>
+ public static RawMatrix CreateRawMatrix(this REngine engine, byte[,] matrix)
+ {
+ if (engine == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (!engine.IsRunning)
+ {
+ throw new ArgumentException();
+ }
+ return new RawMatrix(engine, matrix);
+ }
+ }
+}
diff --git a/rdotnet/R.NET/RawMatrix.cs b/rdotnet/R.NET/RawMatrix.cs
new file mode 100644
index 0000000..389d370
--- /dev/null
+++ b/rdotnet/R.NET/RawMatrix.cs
@@ -0,0 +1,94 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A matrix of byte values.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class RawMatrix : Matrix<byte>
+ {
+ /// <summary>
+ /// Creates a new RawMatrix with the specified size.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="rowCount">The row size.</param>
+ /// <param name="columnCount">The column size.</param>
+ /// <seealso cref="REngineExtension.CreateRawMatrix(REngine, int, int)"/>
+ public RawMatrix(REngine engine, int rowCount, int columnCount)
+ : base(engine, SymbolicExpressionType.RawVector, rowCount, columnCount)
+ {}
+
+ /// <summary>
+ /// Creates a new RawMatrix with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="matrix">The values.</param>
+ /// <seealso cref="REngineExtension.CreateRawMatrix(REngine, byte[,])"/>
+ public RawMatrix(REngine engine, byte[,] matrix)
+ : base(engine, SymbolicExpressionType.RawVector, matrix)
+ {}
+
+ /// <summary>
+ /// Creates a new instance for a raw matrix.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a raw matrix.</param>
+ protected internal RawMatrix(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="rowIndex">The zero-based rowIndex index of the element to get or set.</param>
+ /// <param name="columnIndex">The zero-based columnIndex index of the element to get or
set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override byte this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex < 0 || RowCount <= rowIndex)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex < 0 || ColumnCount <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(rowIndex, columnIndex);
+ return Marshal.ReadByte(DataPointer, offset);
+ }
+ }
+ set
+ {
+ if (rowIndex < 0 || RowCount <= rowIndex)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex < 0 || ColumnCount <= columnIndex)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(rowIndex, columnIndex);
+ Marshal.WriteByte(DataPointer, offset, value);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of an Raw in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get { return sizeof(byte); }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/RawVector.cs b/rdotnet/R.NET/RawVector.cs
new file mode 100644
index 0000000..1b0d215
--- /dev/null
+++ b/rdotnet/R.NET/RawVector.cs
@@ -0,0 +1,128 @@
+ïusing System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A sequence of byte values.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class RawVector : Vector<byte>
+ {
+ /// <summary>
+ /// Creates a new RawVector with the specified length.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="length">The length.</param>
+ public RawVector(REngine engine, int length)
+ : base(engine, SymbolicExpressionType.RawVector, length)
+ {}
+
+ /// <summary>
+ /// Creates a new RawVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="vector">The values.</param>
+ /// <seealso cref="REngineExtension.CreateRawVector(REngine, IEnumerable{byte})"/>
+ public RawVector(REngine engine, IEnumerable<byte> vector)
+ : base(engine, SymbolicExpressionType.RawVector, vector)
+ {}
+
+ /// <summary>
+ /// Creates a new RawVector with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="vector">The values.</param>
+ /// <seealso cref="REngineExtension.CreateRawVector(REngine, int)"/>
+ public RawVector(REngine engine, byte[] vector)
+ : base(engine, SymbolicExpressionType.RawVector, vector.Length)
+ {
+ Marshal.Copy(vector, 0, DataPointer, vector.Length);
+ }
+
+ /// <summary>
+ /// Creates a new instance for a raw vector.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a raw vector.</param>
+ /// <seealso cref="REngineExtension.CreateRawVector(REngine, byte[])"/>
+ protected internal RawVector(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index of the element to get or set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public override byte this[int index]
+ {
+ get
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(index);
+ return Marshal.ReadByte(DataPointer, offset);
+ }
+ }
+ set
+ {
+ if (index < 0 || Length <= index)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ using (new ProtectedPointer(this))
+ {
+ int offset = GetOffset(index);
+ Marshal.WriteByte(DataPointer, offset, value);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of a byte value in byte.
+ /// </summary>
+ protected override int DataSize
+ {
+ get { return sizeof(byte); }
+ }
+
+ /// <summary>
+ /// Copies the elements to the specified array.
+ /// </summary>
+ /// <param name="destination">The destination array.</param>
+ /// <param name="length">The length to copy.</param>
+ /// <param name="sourceIndex">The first index of the vector.</param>
+ /// <param name="destinationIndex">The first index of the destination array.</param>
+ public new void CopyTo(byte[] destination, int length, int sourceIndex = 0, int
destinationIndex = 0)
+ {
+ if (destination == null)
+ {
+ throw new ArgumentNullException("destination");
+ }
+ if (length < 0)
+ {
+ throw new IndexOutOfRangeException("length");
+ }
+ if (sourceIndex < 0 || Length < sourceIndex + length)
+ {
+ throw new IndexOutOfRangeException("sourceIndex");
+ }
+ if (destinationIndex < 0 || destination.Length < destinationIndex + length)
+ {
+ throw new IndexOutOfRangeException("destinationIndex");
+ }
+
+ int offset = GetOffset(sourceIndex);
+ IntPtr pointer = IntPtr.Add(DataPointer, offset);
+ Marshal.Copy(pointer, destination, destinationIndex, length);
+ }
+ }
+}
diff --git a/rdotnet/R.NET/SpecialFunction.cs b/rdotnet/R.NET/SpecialFunction.cs
new file mode 100644
index 0000000..77de3ee
--- /dev/null
+++ b/rdotnet/R.NET/SpecialFunction.cs
@@ -0,0 +1,34 @@
+ïusing System;
+using System.Linq;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A special function.
+ /// </summary>
+ public class SpecialFunction : Function
+ {
+ /// <summary>
+ /// Creates a special function proxy.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="pointer">The pointer.</param>
+ protected internal SpecialFunction(REngine engine, IntPtr pointer)
+ : base(engine, pointer)
+ {}
+
+ public override SymbolicExpression Invoke(SymbolicExpression[] args)
+ {
+ IntPtr argument = Engine.NilValue.DangerousGetHandle();
+ foreach (SymbolicExpression arg in args.Reverse())
+ {
+ argument = Engine.GetFunction<Rf_cons>("Rf_cons")(arg.DangerousGetHandle(),
argument);
+ }
+ IntPtr call = Engine.GetFunction<Rf_lcons>("Rf_lcons")(handle, argument);
+
+ IntPtr result = Engine.GetFunction<Rf_eval>("Rf_eval")(call,
Engine.GlobalEnvironment.DangerousGetHandle());
+ return new SymbolicExpression(Engine, result);
+ }
+ }
+}
diff --git a/rdotnet/R.NET/StartupParameter.cs b/rdotnet/R.NET/StartupParameter.cs
new file mode 100644
index 0000000..33aba52
--- /dev/null
+++ b/rdotnet/R.NET/StartupParameter.cs
@@ -0,0 +1,298 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using RDotNet.Internals;
+using RDotNet.Internals.Windows;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// Represents parameters on R's startup.
+ /// </summary>
+ /// <remarks>
+ /// Wraps RStart struct.
+ /// </remarks>
+ public class StartupParameter
+ {
+ private static readonly ulong EnvironmentDependentMaxSize = Environment.Is64BitProcess ?
ulong.MaxValue : uint.MaxValue;
+
+ // Windows style RStart includes Unix-style RStart.
+ internal RStart start;
+
+ public StartupParameter()
+ {
+ this.start = new RStart();
+ SetDefaultParameter();
+ }
+
+ /// <summary>
+ /// Gets or sets the value indicating that R runs as quiet mode.
+ /// </summary>
+ public bool Quiet
+ {
+ get { return this.start.Common.R_Quiet; }
+ set { this.start.Common.R_Quiet = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the value indicating that R runs as slave mode.
+ /// </summary>
+ public bool Slave
+ {
+ get { return this.start.Common.R_Slave; }
+ set { this.start.Common.R_Slave = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the value indicating that R runs as interactive mode.
+ /// </summary>
+ public bool Interactive
+ {
+ get { return this.start.Common.R_Interactive; }
+ set { this.start.Common.R_Interactive = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the value indicating that R runs as verbose mode.
+ /// </summary>
+ public bool Verbose
+ {
+ get { return this.start.Common.R_Verbose; }
+ set { this.start.Common.R_Verbose = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the value indicating that R loads the site file.
+ /// </summary>
+ public bool LoadSiteFile
+ {
+ get { return this.start.Common.LoadSiteFile; }
+ set { this.start.Common.LoadSiteFile = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the value indicating that R loads the init file.
+ /// </summary>
+ public bool LoadInitFile
+ {
+ get { return this.start.Common.LoadInitFile; }
+ set { this.start.Common.LoadInitFile = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the value indicating that R debugs the init file.
+ /// </summary>
+ public bool DebugInitFile
+ {
+ get { return this.start.Common.DebugInitFile; }
+ set { this.start.Common.DebugInitFile = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the value indicating that R restores the history.
+ /// </summary>
+ public StartupRestoreAction RestoreAction
+ {
+ get { return this.start.Common.RestoreAction; }
+ set { this.start.Common.RestoreAction = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the value indicating that R saves the history.
+ /// </summary>
+ public StartupSaveAction SaveAction
+ {
+ get { return this.start.Common.SaveAction; }
+ set { this.start.Common.SaveAction = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the minimum memory size.
+ /// </summary>
+ public ulong MinMemorySize
+ {
+ get { return this.start.Common.vsize.ToUInt64(); }
+ set
+ {
+ if (value > EnvironmentDependentMaxSize)
+ {
+ throw new ArgumentOutOfRangeException("value");
+ }
+ this.start.Common.vsize = new UIntPtr(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the minimum number of cons cells.
+ /// </summary>
+ public ulong MinCellSize
+ {
+ get { return this.start.Common.nsize.ToUInt64(); }
+ set
+ {
+ if (value > EnvironmentDependentMaxSize)
+ {
+ throw new ArgumentOutOfRangeException("value");
+ }
+ this.start.Common.nsize = new UIntPtr(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the maximum memory size.
+ /// </summary>
+ public ulong MaxMemorySize
+ {
+ get { return this.start.Common.max_vsize.ToUInt64(); }
+ set
+ {
+ if (value > EnvironmentDependentMaxSize)
+ {
+ throw new ArgumentOutOfRangeException("value");
+ }
+ this.start.Common.max_vsize = new UIntPtr(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the maximum number of cons cells.
+ /// </summary>
+ public ulong MaxCellSize
+ {
+ get { return this.start.Common.max_nsize.ToUInt64(); }
+ set
+ {
+ if (value > EnvironmentDependentMaxSize)
+ {
+ throw new ArgumentOutOfRangeException("value");
+ }
+ this.start.Common.max_nsize = new UIntPtr(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the maximum number of protected pointers in stack.
+ /// </summary>
+ public ulong StackSize
+ {
+ get { return this.start.Common.ppsize.ToUInt64(); }
+ set
+ {
+ if (value > EnvironmentDependentMaxSize)
+ {
+ throw new ArgumentOutOfRangeException("value");
+ }
+ this.start.Common.ppsize = new UIntPtr(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the value indicating that R does NOT load the environment file.
+ /// </summary>
+ public bool NoRenviron
+ {
+ get { return this.start.Common.NoRenviron; }
+ set { this.start.Common.NoRenviron = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the base directory in which R is installed.
+ /// </summary>
+ /// <remarks>
+ /// Only Windows.
+ /// </remarks>
+ public string RHome
+ {
+ get
+ {
+ if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+ {
+ throw new NotSupportedException();
+ }
+ return Marshal.PtrToStringAnsi(this.start.rhome);
+ }
+ set
+ {
+ if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+ {
+ throw new NotSupportedException();
+ }
+ this.start.rhome = Marshal.StringToHGlobalAnsi(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the default user workspace.
+ /// </summary>
+ /// <remarks>
+ /// Only Windows.
+ /// </remarks>
+ public string Home
+ {
+ get
+ {
+ if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+ {
+ throw new NotSupportedException();
+ }
+ return Marshal.PtrToStringAnsi(this.start.home);
+ }
+ set
+ {
+ if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+ {
+ throw new NotSupportedException();
+ }
+ this.start.home = Marshal.StringToHGlobalAnsi(value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the UI mode.
+ /// </summary>
+ /// <remarks>
+ /// Only Windows.
+ /// </remarks>
+ public UiMode CharacterMode
+ {
+ get
+ {
+ if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+ {
+ throw new NotSupportedException();
+ }
+ return this.start.CharacterMode;
+ }
+ set
+ {
+ if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+ {
+ throw new NotSupportedException();
+ }
+ this.start.CharacterMode = value;
+ }
+ }
+
+ private void SetDefaultParameter()
+ {
+ Quiet = true;
+ //Slave = false;
+ Interactive = true;
+ //Verbose = false;
+ RestoreAction = StartupRestoreAction.NoRestore;
+ SaveAction = StartupSaveAction.NoSave;
+ LoadSiteFile = true;
+ LoadInitFile = true;
+ //DebugInitFile = false;
+ MinMemorySize = 6291456;
+ MinCellSize = 350000;
+ MaxMemorySize = EnvironmentDependentMaxSize;
+ MaxCellSize = EnvironmentDependentMaxSize;
+ StackSize = 50000;
+ //NoRenviron = false;
+ if (Environment.OSVersion.Platform == PlatformID.Win32NT)
+ {
+ CharacterMode = UiMode.LinkDll;
+ }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Symbol.cs b/rdotnet/R.NET/Symbol.cs
new file mode 100644
index 0000000..c08f55b
--- /dev/null
+++ b/rdotnet/R.NET/Symbol.cs
@@ -0,0 +1,76 @@
+ïusing System;
+using System.Runtime.InteropServices;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A symbol object.
+ /// </summary>
+ public class Symbol : SymbolicExpression
+ {
+ /// <summary>
+ /// Creates a symbol.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="pointer">The pointer.</param>
+ protected internal Symbol(REngine engine, IntPtr pointer)
+ : base(engine, pointer)
+ {}
+
+ /// <summary>
+ /// Gets and sets the name.
+ /// </summary>
+ public string PrintName
+ {
+ get
+ {
+ SEXPREC sexp = GetInternalStructure();
+ return new InternalString(Engine, sexp.symsxp.pname).ToString();
+ }
+ set
+ {
+ IntPtr pointer = (value == null ? Engine.NilValue : new
InternalString(Engine, value)).DangerousGetHandle();
+ int offset = GetOffsetOf("pname");
+ Marshal.WriteIntPtr(handle, offset, pointer);
+ }
+ }
+
+ /// <summary>
+ /// Gets the internal function.
+ /// </summary>
+ public SymbolicExpression Internal
+ {
+ get
+ {
+ SEXPREC sexp = GetInternalStructure();
+ if (Engine.CheckNil(sexp.symsxp.value))
+ {
+ return null;
+ }
+ return new SymbolicExpression(Engine, sexp symsxp internal);
+ }
+ }
+
+ /// <summary>
+ /// Gets the symbol value.
+ /// </summary>
+ public SymbolicExpression Value
+ {
+ get
+ {
+ SEXPREC sexp = GetInternalStructure();
+ if (Engine.CheckNil(sexp.symsxp.value))
+ {
+ return null;
+ }
+ return new SymbolicExpression(Engine, sexp.symsxp.value);
+ }
+ }
+
+ private static int GetOffsetOf(string fieldName)
+ {
+ return Marshal.OffsetOf(typeof(SEXPREC), "u").ToInt32() +
Marshal.OffsetOf(typeof(symsxp), fieldName).ToInt32();
+ }
+ }
+}
diff --git a/rdotnet/R.NET/SymbolicExpression.cs b/rdotnet/R.NET/SymbolicExpression.cs
new file mode 100644
index 0000000..c127f17
--- /dev/null
+++ b/rdotnet/R.NET/SymbolicExpression.cs
@@ -0,0 +1,239 @@
+ïusing System;
+using System.Dynamic;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Dynamic;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// An expression in R environment.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class SymbolicExpression : SafeHandle, IEquatable<SymbolicExpression>,
IDynamicMetaObjectProvider
+ {
+ private readonly REngine engine;
+ private readonly SEXPREC sexp;
+
+ private bool isProtected;
+
+ /// <summary>
+ /// Creates new instance of SymbolicExpression.
+ /// </summary>
+ /// <param name="engine">The engine.</param>
+ /// <param name="pointer">The pointer.</param>
+ protected internal SymbolicExpression(REngine engine, IntPtr pointer)
+ : base(IntPtr.Zero, true)
+ {
+ this.engine = engine;
+ this.sexp = (SEXPREC)Marshal.PtrToStructure(pointer, typeof(SEXPREC));
+ SetHandle(pointer);
+ }
+
+ public override bool IsInvalid
+ {
+ get { return IsClosed || handle == IntPtr.Zero; }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="REngine"/> to which this expression belongs.
+ /// </summary>
+ public REngine Engine
+ {
+ get { return this.engine; }
+ }
+
+ /// <summary>
+ /// Gets whether this expression is protected from the garbage collection.
+ /// </summary>
+ public bool IsProtected
+ {
+ get { return this.isProtected; }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="SymbolicExpressionType"/>.
+ /// </summary>
+ public SymbolicExpressionType Type
+ {
+ get { return this.sexp.sxpinfo.type; }
+ }
+
+ #region IDynamicMetaObjectProvider Members
+
+ public virtual DynamicMetaObject GetMetaObject(System.Linq.Expressions.Expression parameter)
+ {
+ return new SymbolicExpressionDynamicMeta(parameter, this);
+ }
+
+ #endregion
+
+ #region IEquatable<SymbolicExpression> Members
+
+ public bool Equals(SymbolicExpression other)
+ {
+ return other != null && handle == other.handle;
+ }
+
+ #endregion
+
+ internal SEXPREC GetInternalStructure()
+ {
+ return (SEXPREC)Marshal.PtrToStructure(handle, typeof(SEXPREC));
+ }
+
+ /// <summary>
+ /// Gets all value names.
+ /// </summary>
+ /// <returns>The names of attributes</returns>
+ public string[] GetAttributeNames()
+ {
+ int length = Engine.GetFunction<Rf_length>("Rf_length")(this.sexp.attrib);
+ var names = new string[length];
+ IntPtr pointer = this.sexp.attrib;
+ for (int index = 0; index < length; index++)
+ {
+ var node = (SEXPREC)Marshal.PtrToStructure(pointer, typeof(SEXPREC));
+ var attribute = (SEXPREC)Marshal.PtrToStructure(node.listsxp.tagval,
typeof(SEXPREC));
+ IntPtr name = attribute.symsxp.pname;
+ names[index] = new InternalString(Engine, name);
+ pointer = node.listsxp.cdrval;
+ }
+ return names;
+ }
+
+ /// <summary>
+ /// Gets the value of the specified name.
+ /// </summary>
+ /// <param name="attributeName">The name of attribute.</param>
+ /// <returns>The attribute.</returns>
+ public SymbolicExpression GetAttribute(string attributeName)
+ {
+ if (attributeName == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (attributeName == string.Empty)
+ {
+ throw new ArgumentException();
+ }
+
+ IntPtr installedName = Engine.GetFunction<Rf_install>("Rf_install")(attributeName);
+ IntPtr attribute = Engine.GetFunction<Rf_getAttrib>("Rf_getAttrib")(handle,
installedName);
+ if (Engine.CheckNil(attribute))
+ {
+ return null;
+ }
+ return new SymbolicExpression(Engine, attribute);
+ }
+
+ internal SymbolicExpression GetAttribute(SymbolicExpression symbol)
+ {
+ if (symbol == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (symbol.Type != SymbolicExpressionType.Symbol)
+ {
+ throw new ArgumentException();
+ }
+
+ IntPtr attribute = Engine.GetFunction<Rf_getAttrib>("Rf_getAttrib")(handle,
symbol.handle);
+ if (Engine.CheckNil(attribute))
+ {
+ return null;
+ }
+ return new SymbolicExpression(Engine, attribute);
+ }
+
+ /// <summary>
+ /// Sets the new value to the attribute of the specified name.
+ /// </summary>
+ /// <param name="attributeName">The name of attribute.</param>
+ /// <param name="value">The value</param>
+ public void SetAttribute(string attributeName, SymbolicExpression value)
+ {
+ if (attributeName == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (attributeName == string.Empty)
+ {
+ throw new ArgumentException();
+ }
+
+ if (value == null)
+ {
+ value = Engine.NilValue;
+ }
+
+ IntPtr installedName = Engine.GetFunction<Rf_install>("Rf_install")(attributeName);
+ Engine.GetFunction<Rf_setAttrib>("Rf_setAttrib")(handle, installedName, value.handle);
+ }
+
+ internal void SetAttribute(SymbolicExpression symbol, SymbolicExpression value)
+ {
+ if (symbol == null)
+ {
+ throw new ArgumentNullException();
+ }
+ if (symbol.Type != SymbolicExpressionType.Symbol)
+ {
+ throw new ArgumentException();
+ }
+
+ if (value == null)
+ {
+ value = Engine.NilValue;
+ }
+
+ Engine.GetFunction<Rf_setAttrib>("Rf_setAttrib")(handle, symbol.handle, value.handle);
+ }
+
+ /// <summary>
+ /// Prevents the expression from R's garbage collector.
+ /// </summary>
+ /// <seealso cref="SymbolicExpression.Unprotect"/>
+ public void Protect()
+ {
+ if (!IsInvalid)
+ {
+ Engine.GetFunction<Rf_protect>("Rf_protect")(handle);
+ this.isProtected = true;
+ }
+ }
+
+ /// <summary>
+ /// Stops protection.
+ /// </summary>
+ /// <seealso cref="SymbolicExpression.Protect"/>
+ public void Unprotect()
+ {
+ if (!IsInvalid && IsProtected)
+ {
+ Engine.GetFunction<Rf_unprotect_ptr>("Rf_unprotect_ptr")(handle);
+ this.isProtected = false;
+ }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ if (IsProtected)
+ {
+ Unprotect();
+ }
+ return true;
+ }
+
+ public override int GetHashCode()
+ {
+ return handle.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return Equals(obj as SymbolicExpression);
+ }
+ }
+}
diff --git a/rdotnet/R.NET/SymbolicExpressionExtension.cs b/rdotnet/R.NET/SymbolicExpressionExtension.cs
new file mode 100644
index 0000000..5d25a9b
--- /dev/null
+++ b/rdotnet/R.NET/SymbolicExpressionExtension.cs
@@ -0,0 +1,586 @@
+ïusing System;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// Provides extension methods for <see cref="SymbolicExpression"/>.
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public static class SymbolicExpressionExtension
+ {
+ /// <summary>
+ /// Gets whether the specified expression is list.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns><c>True</c> if the specified expression is list.</returns>
+ public static bool IsList(this SymbolicExpression expression)
+ {
+ if (expression == null)
+ {
+ throw new ArgumentNullException();
+ }
+ return
expression.Engine.GetFunction<Rf_isList>("Rf_isList")(expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a GenericVector.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The GenericVector. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static GenericVector AsList(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+ return new GenericVector(expression.Engine, expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a DataFrame.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The DataFrame. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static DataFrame AsDataFrame(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+ return new DataFrame(expression.Engine, expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Gets whether the specified expression is vector.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns><c>True</c> if the specified expression is vector.</returns>
+ public static bool IsVector(this SymbolicExpression expression)
+ {
+ if (expression == null)
+ {
+ throw new ArgumentNullException();
+ }
+ return
expression.Engine.GetFunction<Rf_isVector>("Rf_isVector")(expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a DynamicVector.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The DynamicVector. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static DynamicVector AsVector(this SymbolicExpression expression)
+ {
+ if (expression == null)
+ {
+ throw new ArgumentNullException();
+ }
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
expression.Type);
+ return new DynamicVector(expression.Engine, coerced);
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a LogicalVector.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The LogicalVector. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static LogicalVector AsLogical(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
SymbolicExpressionType.LogicalVector);
+ return new LogicalVector(expression.Engine, coerced);
+ }
+
+ /// <summary>
+ /// Converts the specified expression to an IntegerVector.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The LogicalVector. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static IntegerVector AsInteger(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
SymbolicExpressionType.IntegerVector);
+ return new IntegerVector(expression.Engine, coerced);
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a NumericVector.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The LogicalVector. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static NumericVector AsNumeric(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
SymbolicExpressionType.NumericVector);
+ return new NumericVector(expression.Engine, coerced);
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a CharacterVector.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The LogicalVector. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static CharacterVector AsCharacter(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
SymbolicExpressionType.CharacterVector);
+ return new CharacterVector(expression.Engine, coerced);
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a ComplexVector.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The LogicalVector. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static ComplexVector AsComplex(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
SymbolicExpressionType.ComplexVector);
+ return new ComplexVector(expression.Engine, coerced);
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a RawVector.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The LogicalVector. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static RawVector AsRaw(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
SymbolicExpressionType.RawVector);
+ return new RawVector(expression.Engine, coerced);
+ }
+
+ /// <summary>
+ /// Gets whether the specified expression is matrix.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns><c>True</c> if the specified expression is matrix.</returns>
+ public static bool IsMatrix(this SymbolicExpression expression)
+ {
+ if (expression == null)
+ {
+ throw new ArgumentNullException();
+ }
+ return
expression.Engine.GetFunction<Rf_isMatrix>("Rf_isMatrix")(expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a LogicalMatrix.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The LogicalMatrix. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static LogicalMatrix AsLogicalMatrix(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+
+ int rowCount = 0;
+ int columnCount = 0;
+
+ if (expression.IsMatrix())
+ {
+ if (expression.Type == SymbolicExpressionType.LogicalVector)
+ {
+ return new LogicalMatrix(expression.Engine,
expression.DangerousGetHandle());
+ }
+ else
+ {
+ rowCount =
expression.Engine.GetFunction<Rf_nrows>("Rf_nrows")(expression.DangerousGetHandle());
+ columnCount =
expression.Engine.GetFunction<Rf_ncols>("Rf_ncols")(expression.DangerousGetHandle());
+ }
+ }
+
+ if (columnCount == 0)
+ {
+ rowCount =
expression.Engine.GetFunction<Rf_length>("Rf_length")(expression.DangerousGetHandle());
+ columnCount = 1;
+ }
+
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
SymbolicExpressionType.LogicalVector);
+ var dim = new IntegerVector(expression.Engine, new[] { rowCount, columnCount });
+ SymbolicExpression dimSymbol = expression.Engine.GetPredefinedSymbol("R_DimSymbol");
+ var matrix = new LogicalMatrix(expression.Engine, coerced);
+ matrix.SetAttribute(dimSymbol, dim);
+ return matrix;
+ }
+
+ /// <summary>
+ /// Converts the specified expression to an IntegerMatrix.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The IntegerMatrix. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static IntegerMatrix AsIntegerMatrix(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+
+ int rowCount = 0;
+ int columnCount = 0;
+
+ if (expression.IsMatrix())
+ {
+ if (expression.Type == SymbolicExpressionType.IntegerVector)
+ {
+ return new IntegerMatrix(expression.Engine,
expression.DangerousGetHandle());
+ }
+ else
+ {
+ rowCount =
expression.Engine.GetFunction<Rf_nrows>("Rf_nrows")(expression.DangerousGetHandle());
+ columnCount =
expression.Engine.GetFunction<Rf_ncols>("Rf_ncols")(expression.DangerousGetHandle());
+ }
+ }
+
+ if (columnCount == 0)
+ {
+ rowCount =
expression.Engine.GetFunction<Rf_length>("Rf_length")(expression.DangerousGetHandle());
+ columnCount = 1;
+ }
+
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
SymbolicExpressionType.IntegerVector);
+ var dim = new IntegerVector(expression.Engine, new[] { rowCount, columnCount });
+ SymbolicExpression dimSymbol = expression.Engine.GetPredefinedSymbol("R_DimSymbol");
+ var matrix = new IntegerMatrix(expression.Engine, coerced);
+ matrix.SetAttribute(dimSymbol, dim);
+ return matrix;
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a NumericMatrix.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The NumericMatrix. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static NumericMatrix AsNumericMatrix(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+
+ int rowCount = 0;
+ int columnCount = 0;
+
+ if (expression.IsMatrix())
+ {
+ if (expression.Type == SymbolicExpressionType.NumericVector)
+ {
+ return new NumericMatrix(expression.Engine,
expression.DangerousGetHandle());
+ }
+ else
+ {
+ rowCount =
expression.Engine.GetFunction<Rf_nrows>("Rf_nrows")(expression.DangerousGetHandle());
+ columnCount =
expression.Engine.GetFunction<Rf_ncols>("Rf_ncols")(expression.DangerousGetHandle());
+ }
+ }
+
+ if (columnCount == 0)
+ {
+ rowCount =
expression.Engine.GetFunction<Rf_length>("Rf_length")(expression.DangerousGetHandle());
+ columnCount = 1;
+ }
+
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
SymbolicExpressionType.NumericVector);
+ var dim = new IntegerVector(expression.Engine, new[] { rowCount, columnCount });
+ SymbolicExpression dimSymbol = expression.Engine.GetPredefinedSymbol("R_DimSymbol");
+ var matrix = new NumericMatrix(expression.Engine, coerced);
+ matrix.SetAttribute(dimSymbol, dim);
+ return matrix;
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a CharacterMatrix.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The CharacterMatrix. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static CharacterMatrix AsCharacterMatrix(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+
+ int rowCount = 0;
+ int columnCount = 0;
+
+ if (expression.IsMatrix())
+ {
+ if (expression.Type == SymbolicExpressionType.CharacterVector)
+ {
+ return new CharacterMatrix(expression.Engine,
expression.DangerousGetHandle());
+ }
+ else
+ {
+ rowCount =
expression.Engine.GetFunction<Rf_nrows>("Rf_nrows")(expression.DangerousGetHandle());
+ columnCount =
expression.Engine.GetFunction<Rf_ncols>("Rf_ncols")(expression.DangerousGetHandle());
+ }
+ }
+
+ if (columnCount == 0)
+ {
+ rowCount =
expression.Engine.GetFunction<Rf_length>("Rf_length")(expression.DangerousGetHandle());
+ columnCount = 1;
+ }
+
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
SymbolicExpressionType.CharacterVector);
+ var dim = new IntegerVector(expression.Engine, new[] { rowCount, columnCount });
+ SymbolicExpression dimSymbol = expression.Engine.GetPredefinedSymbol("R_DimSymbol");
+ var matrix = new CharacterMatrix(expression.Engine, coerced);
+ matrix.SetAttribute(dimSymbol, dim);
+ return matrix;
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a ComplexMatrix.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The ComplexMatrix. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static ComplexMatrix AsComplexMatrix(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+
+ int rowCount = 0;
+ int columnCount = 0;
+
+ if (expression.IsMatrix())
+ {
+ if (expression.Type == SymbolicExpressionType.ComplexVector)
+ {
+ return new ComplexMatrix(expression.Engine,
expression.DangerousGetHandle());
+ }
+ else
+ {
+ rowCount =
expression.Engine.GetFunction<Rf_nrows>("Rf_nrows")(expression.DangerousGetHandle());
+ columnCount =
expression.Engine.GetFunction<Rf_ncols>("Rf_ncols")(expression.DangerousGetHandle());
+ }
+ }
+
+ if (columnCount == 0)
+ {
+ rowCount =
expression.Engine.GetFunction<Rf_length>("Rf_length")(expression.DangerousGetHandle());
+ columnCount = 1;
+ }
+
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
SymbolicExpressionType.ComplexVector);
+ var dim = new IntegerVector(expression.Engine, new[] { rowCount, columnCount });
+ SymbolicExpression dimSymbol = expression.Engine.GetPredefinedSymbol("R_DimSymbol");
+ var matrix = new ComplexMatrix(expression.Engine, coerced);
+ matrix.SetAttribute(dimSymbol, dim);
+ return matrix;
+ }
+
+ /// <summary>
+ /// Converts the specified expression to a RawMatrix.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The RawMatrix. Returns <c>null</c> if the specified expression is not
vector.</returns>
+ public static RawMatrix AsRawMatrix(this SymbolicExpression expression)
+ {
+ if (!expression.IsVector())
+ {
+ return null;
+ }
+
+ int rowCount = 0;
+ int columnCount = 0;
+
+ if (expression.IsMatrix())
+ {
+ if (expression.Type == SymbolicExpressionType.RawVector)
+ {
+ return new RawMatrix(expression.Engine,
expression.DangerousGetHandle());
+ }
+ else
+ {
+ rowCount =
expression.Engine.GetFunction<Rf_nrows>("Rf_nrows")(expression.DangerousGetHandle());
+ columnCount =
expression.Engine.GetFunction<Rf_ncols>("Rf_ncols")(expression.DangerousGetHandle());
+ }
+ }
+
+ if (columnCount == 0)
+ {
+ rowCount =
expression.Engine.GetFunction<Rf_length>("Rf_length")(expression.DangerousGetHandle());
+ columnCount = 1;
+ }
+
+ IntPtr coerced =
expression.Engine.GetFunction<Rf_coerceVector>("Rf_coerceVector")(expression.DangerousGetHandle(),
SymbolicExpressionType.RawVector);
+ var dim = new IntegerVector(expression.Engine, new[] { rowCount, columnCount });
+ SymbolicExpression dimSymbol = expression.Engine.GetPredefinedSymbol("R_DimSymbol");
+ var matrix = new RawMatrix(expression.Engine, coerced);
+ matrix.SetAttribute(dimSymbol, dim);
+ return matrix;
+ }
+
+ /// <summary>
+ /// Specifies the expression is an <see cref="REnvironment"/> object or not.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns><c>True</c> if it is an environment.</returns>
+ public static bool IsEnvironment(this SymbolicExpression expression)
+ {
+ if (expression == null)
+ {
+ throw new ArgumentNullException();
+ }
+ return
expression.Engine.GetFunction<Rf_isEnvironment>("Rf_isEnvironment")(expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Gets the expression as an <see cref="REnvironment"/>.
+ /// </summary>
+ /// <param name="expression">The environment.</param>
+ /// <returns>The environment.</returns>
+ public static REnvironment AsEnvironment(this SymbolicExpression expression)
+ {
+ if (!expression.IsEnvironment())
+ {
+ return null;
+ }
+ return new REnvironment(expression.Engine, expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Specifies the expression is an <see cref="RDotNet.Expression"/> object or not.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns><c>True</c> if it is an expression.</returns>
+ public static bool IsExpression(this SymbolicExpression expression)
+ {
+ if (expression == null)
+ {
+ throw new ArgumentNullException();
+ }
+ return
expression.Engine.GetFunction<Rf_isExpression>("Rf_isExpression")(expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Gets the expression as an <see cref="RDotNet.Expression"/>.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The expression.</returns>
+ public static Expression AsExpression(this SymbolicExpression expression)
+ {
+ if (!expression.IsExpression())
+ {
+ return null;
+ }
+ return new Expression(expression.Engine, expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Specifies the expression is a symbol object or not.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns><c>True</c> if it is a symbol.</returns>
+ public static bool IsSymbol(this SymbolicExpression expression)
+ {
+ if (expression == null)
+ {
+ throw new ArgumentNullException();
+ }
+ return
expression.Engine.GetFunction<Rf_isSymbol>("Rf_isSymbol")(expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Gets the expression as a symbol.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The symbol.</returns>
+ public static Symbol AsSymbol(this SymbolicExpression expression)
+ {
+ if (!expression.IsSymbol())
+ {
+ return null;
+ }
+ return new Symbol(expression.Engine, expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Specifies the expression is a language object or not.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns><c>True</c> if it is a language.</returns>
+ public static bool IsLanguage(this SymbolicExpression expression)
+ {
+ if (expression == null)
+ {
+ throw new ArgumentNullException();
+ }
+ return
expression.Engine.GetFunction<Rf_isLanguage>("Rf_isLanguage")(expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Gets the expression as a language.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The language.</returns>
+ public static Language AsLanguage(this SymbolicExpression expression)
+ {
+ if (!expression.IsLanguage())
+ {
+ return null;
+ }
+ return new Language(expression.Engine, expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Specifies the expression is a function object or not.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns><c>True</c> if it is a function.</returns>
+ public static bool IsFunction(this SymbolicExpression expression)
+ {
+ if (expression == null)
+ {
+ throw new ArgumentNullException();
+ }
+ return
expression.Engine.GetFunction<Rf_isFunction>("Rf_isFunction")(expression.DangerousGetHandle());
+ }
+
+ /// <summary>
+ /// Gets the expression as a function.
+ /// </summary>
+ /// <param name="expression">The expression.</param>
+ /// <returns>The function.</returns>
+ public static Function AsFunction(this SymbolicExpression expression)
+ {
+ switch (expression.Type)
+ {
+ case SymbolicExpressionType.Closure:
+ return new Closure(expression.Engine,
expression.DangerousGetHandle());
+ case SymbolicExpressionType.BuiltinFunction:
+ return new BuiltinFunction(expression.Engine,
expression.DangerousGetHandle());
+ case SymbolicExpressionType.SpecialFunction:
+ return new SpecialFunction(expression.Engine,
expression.DangerousGetHandle());
+ default:
+ throw new ArgumentException();
+ }
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Utility.cs b/rdotnet/R.NET/Utility.cs
new file mode 100644
index 0000000..8af9bb8
--- /dev/null
+++ b/rdotnet/R.NET/Utility.cs
@@ -0,0 +1,29 @@
+ïusing System;
+
+namespace RDotNet
+{
+ internal static class Utility
+ {
+ public static T[] AddFirst<T>(T value, T[] array)
+ {
+ if (array == null)
+ {
+ return new[] { value };
+ }
+ var newArray = new T[array.Length + 1];
+ newArray[0] = value;
+ Array.Copy(array, 0, newArray, 1, array.Length);
+ return newArray;
+ }
+
+ internal static bool CheckNil(this REngine engine, IntPtr pointer)
+ {
+ return engine.NilValue.DangerousGetHandle() == pointer;
+ }
+
+ internal static bool CheckUnbound(this REngine engine, IntPtr pointer)
+ {
+ return engine.UnboundValue.DangerousGetHandle() == pointer;
+ }
+ }
+}
diff --git a/rdotnet/R.NET/Vector.cs b/rdotnet/R.NET/Vector.cs
new file mode 100644
index 0000000..876e134
--- /dev/null
+++ b/rdotnet/R.NET/Vector.cs
@@ -0,0 +1,206 @@
+ïusing System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using RDotNet.Internals;
+
+namespace RDotNet
+{
+ /// <summary>
+ /// A vector base.
+ /// </summary>
+ /// <typeparam name="T">The element type.</typeparam>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public abstract class Vector<T> : SymbolicExpression, IEnumerable<T>
+ {
+ /// <summary>
+ /// Creates a new vector with the specified size.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="type">The element type.</param>
+ /// <param name="length">The length of vector.</param>
+ protected Vector(REngine engine, SymbolicExpressionType type, int length)
+ : base(engine, engine.GetFunction<Rf_allocVector>("Rf_allocVector")(type, length))
+ {
+ if (length <= 0)
+ {
+ throw new ArgumentOutOfRangeException("length");
+ }
+ var empty = new byte[length * DataSize];
+ Marshal.Copy(empty, 0, DataPointer, empty.Length);
+ }
+
+ /// <summary>
+ /// Creates a new vector with the specified values.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="type">The element type.</param>
+ /// <param name="vector">The elements of vector.</param>
+ protected Vector(REngine engine, SymbolicExpressionType type, IEnumerable<T> vector)
+ : base(engine, engine.GetFunction<Rf_allocVector>("Rf_allocVector")(type,
vector.Count()))
+ {
+ int index = 0;
+ foreach (T element in vector)
+ {
+ this[index++] = element;
+ }
+ }
+
+ /// <summary>
+ /// Creates a new instance for a vector.
+ /// </summary>
+ /// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
+ /// <param name="coerced">The pointer to a vector.</param>
+ protected Vector(REngine engine, IntPtr coerced)
+ : base(engine, coerced)
+ {}
+
+ /// <summary>
+ /// Gets or sets the element at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index of the element to get or set.</param>
+ /// <returns>The element at the specified index.</returns>
+ public abstract T this[int index] { get; set; }
+
+ /// <summary>
+ /// Gets or sets the element at the specified name.
+ /// </summary>
+ /// <param name="name">The name of the element to get or set.</param>
+ /// <returns>The element at the specified name.</returns>
+ public virtual T this[string name]
+ {
+ get
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("name");
+ }
+ string[] names = Names;
+ if (names == null)
+ {
+ throw new InvalidOperationException();
+ }
+ int index = Array.IndexOf(names, name);
+ return this[index];
+ }
+ set
+ {
+ string[] names = Names;
+ if (names == null)
+ {
+ throw new InvalidOperationException();
+ }
+ int index = Array.IndexOf(names, name);
+ this[index] = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of elements.
+ /// </summary>
+ public int Length
+ {
+ get { return Engine.GetFunction<Rf_length>("Rf_length")(handle); }
+ }
+
+ /// <summary>
+ /// Gets the names of elements.
+ /// </summary>
+ public string[] Names
+ {
+ get
+ {
+ SymbolicExpression namesSymbol = Engine.GetPredefinedSymbol("R_NamesSymbol");
+ SymbolicExpression names = GetAttribute(namesSymbol);
+ if (names == null)
+ {
+ return null;
+ }
+ CharacterVector namesVector = names.AsCharacter();
+ if (namesVector == null)
+ {
+ return null;
+ }
+
+ int length = namesVector.Length;
+ var result = new string[length];
+ namesVector.CopyTo(result, length);
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Gets the pointer for the first element.
+ /// </summary>
+ protected IntPtr DataPointer
+ {
+ get { return IntPtr.Add(handle, Marshal.SizeOf(typeof(VECTOR_SEXPREC))); }
+ }
+
+ /// <summary>
+ /// Gets the size of an element in byte.
+ /// </summary>
+ protected abstract int DataSize { get; }
+
+ #region IEnumerable<T> Members
+
+ public IEnumerator<T> GetEnumerator()
+ {
+ for (int index = 0; index < Length; index++)
+ {
+ yield return this[index];
+ }
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Copies the elements to the specified array.
+ /// </summary>
+ /// <param name="destination">The destination array.</param>
+ /// <param name="length">The length to copy.</param>
+ /// <param name="sourceIndex">The first index of the vector.</param>
+ /// <param name="destinationIndex">The first index of the destination array.</param>
+ public void CopyTo(T[] destination, int length, int sourceIndex = 0, int destinationIndex = 0)
+ {
+ if (destination == null)
+ {
+ throw new ArgumentNullException("destination");
+ }
+ if (length < 0)
+ {
+ throw new IndexOutOfRangeException("length");
+ }
+ if (sourceIndex < 0 || Length < sourceIndex + length)
+ {
+ throw new IndexOutOfRangeException("sourceIndex");
+ }
+ if (destinationIndex < 0 || destination.Length < destinationIndex + length)
+ {
+ throw new IndexOutOfRangeException("destinationIndex");
+ }
+
+ while (--length >= 0)
+ {
+ destination[destinationIndex++] = this[sourceIndex++];
+ }
+ }
+
+ /// <summary>
+ /// Gets the offset for the specified index.
+ /// </summary>
+ /// <param name="index">The index.</param>
+ /// <returns>The offset.</returns>
+ protected int GetOffset(int index)
+ {
+ return DataSize * index;
+ }
+ }
+}
diff --git a/rdotnet/RDotNet.NativeLibrary/NativeUtility.cs b/rdotnet/RDotNet.NativeLibrary/NativeUtility.cs
new file mode 100644
index 0000000..94adcf2
--- /dev/null
+++ b/rdotnet/RDotNet.NativeLibrary/NativeUtility.cs
@@ -0,0 +1,50 @@
+ïusing System;
+using System.ComponentModel;
+using System.Diagnostics;
+
+namespace RDotNet.NativeLibrary
+{
+ /// <summary>
+ /// Collection of utility methods for operating systems.
+ /// </summary>
+ public static class NativeUtility
+ {
+ /// <summary>
+ /// Gets the platform on which the current process runs.
+ /// </summary>
+ /// <remarks>
+ /// <see cref="Environment.OSVersion"/>'s platform is not <see cref="PlatformID.MacOSX"/>
even on Mac OS X.
+ /// This method returns <see cref="PlatformID.MacOSX"/> when the current process runs on Mac
OS X.
+ /// This method uses UNIX's uname command to check the operating system,
+ /// so this method cannot check the OS correctly if the PATH environment variable is changed
(will returns <see cref="PlatformID.Unix"/>).
+ /// </remarks>
+ /// <returns>The current platform.</returns>
+ public static PlatformID GetPlatform()
+ {
+ var platform = Environment.OSVersion.Platform;
+ if (platform != PlatformID.Unix)
+ {
+ return platform;
+ }
+ try
+ {
+ using (var uname = new Process())
+ {
+ uname.StartInfo.FileName = "uname";
+ uname.StartInfo.Arguments = "-s";
+ uname.StartInfo.RedirectStandardOutput = true;
+ uname.StartInfo.UseShellExecute = false;
+ uname.StartInfo.CreateNoWindow = true;
+ uname.Start();
+ var kernelName = uname.StandardOutput.ReadLine();
+ uname.WaitForExit();
+ return kernelName == "Darwin" ? PlatformID.MacOSX : platform;
+ }
+ }
+ catch (Win32Exception) // probably no PATH to uname.
+ {
+ return platform;
+ }
+ }
+ }
+}
diff --git a/rdotnet/RDotNet.NativeLibrary/Properties/AssemblyInfo.cs
b/rdotnet/RDotNet.NativeLibrary/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..2d1b310
--- /dev/null
+++ b/rdotnet/RDotNet.NativeLibrary/Properties/AssemblyInfo.cs
@@ -0,0 +1,39 @@
+ïusing System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly : AssemblyTitle("RDotNet.NativeLibrary")]
+[assembly : AssemblyDescription("")]
+[assembly : AssemblyConfiguration("")]
+[assembly : AssemblyCompany("RecycleBin")]
+[assembly : AssemblyProduct("RDotNet.NativeLibrary")]
+[assembly : AssemblyCopyright("Copyright  RecycleBin 2012")]
+[assembly : AssemblyTrademark("")]
+[assembly : AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly : ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly : Guid("8c279a95-edef-4f16-a592-fc8c9b927960")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+
+[assembly : AssemblyVersion("1.0.0.0")]
+[assembly : AssemblyFileVersion("1.0.0.0")]
diff --git a/rdotnet/RDotNet.NativeLibrary/RDotNet.NativeLibrary.csproj
b/rdotnet/RDotNet.NativeLibrary/RDotNet.NativeLibrary.csproj
new file mode 100644
index 0000000..cc86dd6
--- /dev/null
+++ b/rdotnet/RDotNet.NativeLibrary/RDotNet.NativeLibrary.csproj
@@ -0,0 +1,66 @@
+ï<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{2A089A59-0F22-4484-B442-0FE8BDA10879}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>RDotNet.NativeLibrary</RootNamespace>
+ <AssemblyName>RDotNet.NativeLibrary</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>TRACE;DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <DocumentationFile>bin\Debug\RDotNet.NativeLibrary.xml</DocumentationFile>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>none</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <DocumentationFile>bin\Release\RDotNet.NativeLibrary.xml</DocumentationFile>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SignAssembly>true</SignAssembly>
+ </PropertyGroup>
+ <PropertyGroup>
+ <DelaySign>true</DelaySign>
+ </PropertyGroup>
+ <PropertyGroup>
+ <AssemblyOriginatorKeyFile>..\RecycleBin.snk.pub</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="UnmanagedDll.cs" />
+ <Compile Include="NativeUtility.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
diff --git a/rdotnet/RDotNet.NativeLibrary/UnmanagedDll.cs b/rdotnet/RDotNet.NativeLibrary/UnmanagedDll.cs
new file mode 100644
index 0000000..7ddc115
--- /dev/null
+++ b/rdotnet/RDotNet.NativeLibrary/UnmanagedDll.cs
@@ -0,0 +1,207 @@
+ïusing System;
+using System.IO;
+using System.Linq;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+
+namespace RDotNet.NativeLibrary
+{
+ /// <summary>
+ /// A proxy for unmanaged dynamic link library (DLL).
+ /// </summary>
+ [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public class UnmanagedDll : SafeHandle
+ {
+ public override bool IsInvalid
+ {
+ get { return IsClosed || handle == IntPtr.Zero; }
+ }
+
+ /// <summary>
+ /// Creates a proxy for the specified dll.
+ /// </summary>
+ /// <param name="dllName">The DLL's name.</param>
+ public UnmanagedDll(string dllName)
+ : base(IntPtr.Zero, true)
+ {
+ if (dllName == null)
+ {
+ throw new ArgumentNullException("dllName");
+ }
+ if (dllName == string.Empty)
+ {
+ throw new ArgumentException("dllName");
+ }
+
+ IntPtr handle = LoadLibrary(dllName);
+ if (handle == IntPtr.Zero)
+ {
+ throw new DllNotFoundException();
+ }
+ SetHandle(handle);
+ }
+
+ /// <summary>
+ /// Creates the delegate function for the specified function defined in the DLL.
+ /// </summary>
+ /// <typeparam name="TDelegate">The type of delegate.</typeparam>
+ /// <returns>The delegate.</returns>
+ public TDelegate GetFunction<TDelegate>()
+ where TDelegate : class
+ {
+ Type delegateType = typeof(TDelegate);
+ if (!delegateType.IsSubclassOf(typeof(Delegate)))
+ {
+ throw new ArgumentException();
+ }
+ IntPtr function = GetFunctionAddress(handle, delegateType.Name);
+ if (function == IntPtr.Zero)
+ {
+ throw new EntryPointNotFoundException();
+ }
+ return Marshal.GetDelegateForFunctionPointer(function, delegateType) as TDelegate;
+ }
+
+ /// <summary>
+ /// Creates the delegate function for the specified function defined in the DLL.
+ /// </summary>
+ /// <typeparam name="TDelegate">The type of delegate.</typeparam>
+ /// <param name="entryPoint">The name of function.</param>
+ /// <returns>The delegate.</returns>
+ public TDelegate GetFunction<TDelegate>(string entryPoint)
+ where TDelegate : class
+ {
+ if (!typeof(TDelegate).IsSubclassOf(typeof(Delegate)))
+ {
+ throw new ArgumentException();
+ }
+ if (entryPoint == null)
+ {
+ throw new ArgumentNullException("entryPoint");
+ }
+ IntPtr function = GetFunctionAddress(handle, entryPoint);
+ if (function == IntPtr.Zero)
+ {
+ throw new EntryPointNotFoundException();
+ }
+ return Marshal.GetDelegateForFunctionPointer(function, typeof(TDelegate)) as
TDelegate;
+ }
+
+ /// <summary>
+ /// Gets the handle of the specified entry.
+ /// </summary>
+ /// <param name="entryPoint">The name of function.</param>
+ /// <returns>The handle.</returns>
+ public IntPtr DangerousGetHandle(string entryPoint)
+ {
+ if (entryPoint == null)
+ {
+ throw new ArgumentNullException("entryPoint");
+ }
+ return GetFunctionAddress(handle, entryPoint);
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ return FreeLibrary(handle);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (FreeLibrary(handle))
+ {
+ SetHandleAsInvalid();
+ }
+ base.Dispose(disposing);
+ }
+
+ /// <summary>
+ /// Adds a directory to the search path used to locate DLLs for the application.
+ /// </summary>
+ /// <remarks>
+ /// Calls <c>SetDllDirectory</c> in the kernel32.dll on Windows.
+ /// </remarks>
+ /// <param name="dllDirectory">
+ /// The directory to be added to the search path.
+ /// If this parameter is an empty string (""), the call removes the current directory from
the default DLL search order.
+ /// If this parameter is NULL, the function restores the default search order.
+ /// </param>
+ /// <returns>If the function succeeds, the return value is nonzero.</returns>
+ [Obsolete("Set environment variable 'PATH' instead.")]
+#if UNIX
+ public static bool SetDllDirectory(string dllDirectory)
+ {
+ if (dllDirectory == null)
+ {
+ System.Environment.SetEnvironmentVariable(LibraryPath, DefaultSearchPath,
EnvironmentVariableTarget.Process);
+ }
+ else if (dllDirectory == string.Empty)
+ {
+ throw new NotImplementedException();
+ }
+ else
+ {
+ if (!Directory.Exists(dllDirectory))
+ {
+ return false;
+ }
+ string path = System.Environment.GetEnvironmentVariable(LibraryPath,
EnvironmentVariableTarget.Process);
+ if (string.IsNullOrEmpty(path))
+ {
+ path = dllDirectory;
+ }
+ else
+ {
+ path = dllDirectory + Path.PathSeparator + path;
+ }
+ System.Environment.SetEnvironmentVariable(LibraryPath, path,
EnvironmentVariableTarget.Process);
+ }
+ return true;
+ }
+
+ private const string LibraryPath = "PATH";
+ private static readonly string DefaultSearchPath =
System.Environment.GetEnvironmentVariable(LibraryPath, EnvironmentVariableTarget.Process);
+#else
+ [DllImport("kernel32.dll")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool SetDllDirectory([MarshalAs(UnmanagedType.LPStr)] string
dllDirectory);
+#endif
+
+#if UNIX
+ private static IntPtr LoadLibrary(string filename)
+ {
+ const int RTLD_LAZY = 0x1;
+ if (filename.StartsWith("/"))
+ {
+ return dlopen(filename, RTLD_LAZY);
+ }
+ var searchPaths = (Environment.GetEnvironmentVariable("PATH") ??
"").Split(Path.PathSeparator);
+ var dll = searchPaths.Select(directory => Path.Combine(directory,
filename)).FirstOrDefault(File.Exists);
+ return dll == null ? IntPtr.Zero : dlopen(dll, RTLD_LAZY);
+ }
+
+ [DllImport("libdl")]
+ private static extern IntPtr dlopen([MarshalAs(UnmanagedType.LPStr)] string filename, int
flag);
+#else
+ [DllImport("kernel32.dll")]
+ private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);
+#endif
+
+#if UNIX
+ [DllImport("libdl", EntryPoint = "dlclose")]
+#else
+ [DllImport("kernel32.dll")]
+#endif
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ [return : MarshalAs(UnmanagedType.Bool)]
+ private static extern bool FreeLibrary(IntPtr hModule);
+
+#if UNIX
+ [DllImport("libdl", EntryPoint = "dlsym")]
+#else
+ [DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
+#endif
+ private static extern IntPtr GetFunctionAddress(IntPtr hModule,
[MarshalAs(UnmanagedType.LPStr)] string lpProcName);
+ }
+}
diff --git a/rdotnet/RecycleBin.snk.pub b/rdotnet/RecycleBin.snk.pub
new file mode 100644
index 0000000..ce62ad8
Binary files /dev/null and b/rdotnet/RecycleBin.snk.pub differ
diff --git a/src/Makefile.am b/src/Makefile.am
index 8d82212..7089b57 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -355,9 +355,8 @@ REFERENCES = \
-#DLL_REFERENCES = \
-# ../nplot/nplot/bin/NPlot.dll\
-# ../nplot/nplot-gtk/bin/NPlot.Gtk.dll
+DLL_REFERENCES = \
+ ../rdotnet/R.NET/bin/Debug/RDotNet.dll
#CLEANFILES = $(COMMONAPPLICATIONDATA_ROOT) $(COMMONAPPLICATIONDATAROOT_IMAGES)
$(COMMONAPPLICATIONDATAROOT_LOGO) $(PROGRAMFILES) $(LINUX_DESKTOPAPPLICATIONS) $(BINARIES)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]