RInside Version 0.2.12
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
internalfunction_clone.h
Go to the documentation of this file.
1 #pragma once
2 
3 /*
4  * Ok, frankly, this is a hack.
5  * We need an InternalFunction, but we don't have a compatible C++ function - we only have
6  * the parameter count and typeids.
7  *
8  * To do this, we need to get down to the point where the function parameters are nothing but an array of SEXP.
9  * And that's so deep in the CppFunction implementation of Rcpp, that we need some detours to get there.
10  */
11 
12 
13 class CppFunctionForRInsideServer: public Rcpp::CppFunctionBase {
14  public:
15  CppFunctionForRInsideServer(RInsideServer &server, uint32_t callback_id, const std::vector<int32_t> &types) : server(server), callback_id(callback_id), types(types) {
16  }
18  }
19  SEXP operator()(SEXP* args) {
20  // TODO: how do we get the amount of arguments passed? We should probably verify them.
21  BEGIN_RCPP
22  LOG("Callback %u called", callback_id);
25  size_t paramcount = types.size() - 1;
26  for (size_t i=0;i<paramcount;i++) {
27  LOG("Sending parameter %d at %p", (int) i, args[i]);
29  try {
30  server.sexp_to_stream(args[i], types[i+1], true);
31  }
32  catch (const std::exception &e) {
33  LOG("Exception sending argument: %s", e.what());
34  throw;
35  }
36  }
37 
38  LOG("Reading result from stream");
39  SEXP result = server.sexp_from_stream();
41 
42  LOG("Got a SEXP, returning");
43  // TODO: verify result type?
44  return result;
45  END_RCPP
46  }
47  private:
49  uint32_t callback_id;
50  const std::vector<int32_t> types;
51 };
52 
53 // Instantiate the standard deleter. TODO: can we avoid this?
54 template void Rcpp::standard_delete_finalizer(CppFunctionForRInsideServer* obj);
55 
56 
57 namespace Rcpp{
58 
59  // This is a clone of Rcpp's InternalFunction, just with a different constructor.
60  RCPP_API_CLASS(InternalFunctionForRInsideServer_Impl) {
61  public:
62 
63  RCPP_GENERATE_CTOR_ASSIGN(InternalFunctionForRInsideServer_Impl)
64 
65  InternalFunctionForRInsideServer_Impl(RInsideServer &server, uint32_t callback_id, const std::vector<int32_t> &types) {
66  set(XPtr<CppFunctionForRInsideServer>(new CppFunctionForRInsideServer(server, callback_id, types), false));
67  }
68 
69  void update(SEXP){}
70  private:
71 
72  inline void set( SEXP xp){
73  Environment RCPP = Environment::Rcpp_namespace() ;
74  Function intf = RCPP["internal_function"] ;
75  Storage::set__( intf( xp ) ) ;
76  }
77 
78  };
79 
80  typedef InternalFunctionForRInsideServer_Impl<PreserveStorage> InternalFunctionForRInsideServer ;
81 
82 }
InternalFunctionForRInsideServer_Impl< PreserveStorage > InternalFunctionForRInsideServer
BinaryStream stream
Definition: rinsideserver.h:30
SEXP sexp_from_stream()
void allowSendReply()
Definition: rinsideserver.h:36
void write(const char *buffer, size_t len)
const std::vector< int32_t > types
void sexp_to_stream(SEXP, int32_t type, bool include_reply=false)
CppFunctionForRInsideServer(RInsideServer &server, uint32_t callback_id, const std::vector< int32_t > &types)
const char RIS_REPLY_CALLBACK
Definition: constants.h:22
RCPP_API_CLASS(InternalFunctionForRInsideServer_Impl)
void sendReply(char reply)
Definition: rinsideserver.h:35
#define LOG(...)