Refactoring, 1st tier:
[SXSI/xpathcomp.git] / src / common_stub.cpp
diff --git a/src/common_stub.cpp b/src/common_stub.cpp
new file mode 100644 (file)
index 0000000..6f56d33
--- /dev/null
@@ -0,0 +1,92 @@
+#include <unordered_map>
+#include <string>
+
+#include "common_stub.hpp"
+
+extern "C" {
+#include <sys/time.h>
+#include <sys/resource.h>
+}
+
+using std::string;
+using std::pair;
+using std::unordered_map;
+using std::make_pair;
+
+typedef unordered_map<string, pair<struct custom_operations*, size_t>> type_map_t;
+static type_map_t * type_map = 0;
+static value * cpp_exception = 0;
+
+static void init_error()
+{
+  caml_failwith("C++: initialization error");
+}
+
+static void init_exception()
+{
+  cpp_exception = caml_named_value("CPlusPlusError");
+  if (cpp_exception == 0)
+    init_error();
+}
+
+static void init_type_map()
+{
+  if (type_map == 0)
+    type_map = new type_map_t();
+  if (type_map == 0)
+    init_error();
+}
+
+void register_custom_(char* name,
+                     size_t size,
+                     void (*finalize)(value v))
+{
+  if (type_map == 0) init_error();
+  struct custom_operations * ops =
+    (struct custom_operations*) calloc(1, sizeof(struct custom_operations));
+  ops->identifier = name;
+  ops->finalize = finalize;
+  ops->compare = custom_compare_default;
+  ops->hash = custom_hash_default;
+  ops->serialize = custom_serialize_default;
+  ops->deserialize = custom_deserialize_default;
+  type_map->insert(make_pair(string(name), make_pair(ops, size)));
+}
+
+value alloc_custom_(char* name)
+{
+  CAMLparam0();
+  CAMLlocal1(result);
+  if (type_map == 0) init_error();
+  string key = string(name);
+  type_map_t::iterator it = type_map->find(key);
+  if (it == type_map->end())
+    result = Val_unit;
+  else
+    result = caml_alloc_custom(it->second.first, it->second.second, 1, 2);
+
+  CAMLreturn(result);
+}
+
+
+extern "C" value sxsi_cpp_init(value unit)
+{
+  struct rlimit rlim;
+  init_exception();
+  init_type_map();
+
+  /* Set the stack space to unlimited */
+  getrlimit(RLIMIT_STACK, &rlim);
+  if (rlim.rlim_max == RLIM_INFINITY && rlim.rlim_cur != RLIM_INFINITY) {
+    rlim.rlim_cur = RLIM_INFINITY;
+    setrlimit(RLIMIT_STACK, &rlim);
+  };
+
+  return Val_unit;
+}
+
+void sxsi_raise_msg(char * msg)
+{
+  if (cpp_exception == 0) init_error();
+  caml_raise_with_string(*cpp_exception, msg);
+}