These files are copied over from
https://gitlab.com/minizinc/cp-profiler-integration

The repository doesn't have an explicit license assigned to it but it
is assumed to be under same license as the rest of minizinc.
Index: minizinc-ide-2.5.0/cp-profiler/src/cpp-integration/connector.hpp
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ minizinc-ide-2.5.0/cp-profiler/src/cpp-integration/connector.hpp	2020-10-17 16:10:04.029034819 +0300
@@ -0,0 +1,304 @@
+#ifndef CONNECTOR
+#define CONNECTOR
+
+#include "message.hpp"
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <cstring>
+
+#ifdef WIN32
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#pragma comment(lib, "Ws2_32.lib")
+#pragma comment(lib, "Mswsock.lib")
+#pragma comment(lib, "AdvApi32.lib")
+
+#include <basetsd.h>
+typedef SSIZE_T ssize_t;
+
+#else
+
+#include <netdb.h>
+#include <unistd.h>
+
+#endif
+
+namespace cpprofiler {
+
+template <typename T>
+class Option {
+  T value_;
+  bool present{false};
+
+public:
+  bool valid() const { return present; }
+  void set(const T& t) { present = true; value_ = t; }
+  void unset() { present = false; }
+  const T& value() const { assert(present); return value_; }
+  T& value() { assert(present); return value_; }
+};
+
+class Connector;
+class Node;
+static void sendNode(Connector& c, Node& node);
+
+class Node {
+  Connector& _c;
+
+  NodeUID node_;
+  NodeUID parent_;
+  int alt_;
+  int kids_;
+
+  NodeStatus status_;
+
+  Option<std::string> label_;
+  Option<std::string> nogood_;
+  Option<std::string> info_;
+
+public:
+  Node(NodeUID node, NodeUID parent,
+       int alt, int kids, NodeStatus status, Connector& c)
+    : _c(c), node_{node}, parent_{parent},
+      alt_(alt), kids_(kids), status_(status) {}
+
+  Node& set_node_thread_id(int tid) {
+    node_.tid = tid;
+    return *this;
+  }
+
+  const Option<std::string>& label() const { return label_; }
+
+  Node& set_label(const std::string& label) {
+    label_.set(label);
+    return *this;
+  }
+
+  const Option<std::string>& nogood() const { return nogood_; }
+
+  Node& set_nogood(const std::string& nogood) {
+    nogood_.set(nogood);
+    return *this;
+  }
+
+  const Option<std::string>& info() const { return info_; }
+
+  Node& set_info(const std::string& info) {
+    info_.set(info);
+    return *this;
+  }
+
+  int alt() const { return alt_; }
+  int kids() const { return kids_; }
+
+  NodeStatus status() const { return status_; }
+
+  NodeUID nodeUID() const { return node_; }
+  NodeUID parentUID() const { return parent_; }
+
+  int node_id() const { return node_.nid; }
+  int parent_id() const { return parent_.nid; }
+  int node_thread_id() const {  return node_.tid; }
+  int node_restart_id() const { return node_.rid; }
+  int parent_thread_id() const {  return parent_.tid; }
+  int parent_restart_id() const { return parent_.rid; }
+
+  void send() { sendNode(_c, *this); }
+};
+
+// From http://beej.us/guide/bgnet/output/html/multipage/advanced.html#sendall
+static int sendall(int s, const char* buf, int* len) {
+  int total = 0;         // how many bytes we've sent
+  int bytesleft = *len;  // how many we have left to send
+  ssize_t n;
+
+  while (total < *len) {
+    n = send(s, buf + total, static_cast<size_t>(bytesleft), 0);
+    if (n == -1) {
+      break;
+    }
+    total += n;
+    bytesleft -= n;
+  }
+
+  *len = total;  // return number actually sent here
+
+  return n == -1 ? -1 : 0;  // return -1 on failure, 0 on success
+}
+
+class Connector {
+private:
+  MessageMarshalling marshalling;
+
+  const unsigned int port;
+
+  int sockfd;
+  bool _connected;
+
+  void sendOverSocket() {
+    if (!_connected) return;
+
+    std::vector<char> buf = marshalling.serialize();
+
+    sendRawMsg(buf);
+  }
+
+public:
+  void sendRawMsg(const std::vector<char>& buf) {
+    uint32_t bufSize = static_cast<uint32_t>(buf.size());
+    int bufSizeLen = sizeof(uint32_t);
+    sendall(sockfd, reinterpret_cast<char*>(&bufSize), &bufSizeLen);
+    int bufSizeInt = static_cast<int>(bufSize);
+    sendall(sockfd, reinterpret_cast<const char*>(buf.data()), &bufSizeInt);
+  }
+
+  Connector(unsigned int port) : port(port), _connected(false) {}
+
+  bool connected() { return _connected; }
+
+  /// connect to a socket via port specified in the construction (6565 by
+  /// default)
+  void connect() {
+    struct addrinfo hints, *servinfo, *p;
+    int rv;
+
+#ifdef WIN32
+    // Initialise Winsock.
+    WSADATA wsaData;
+    int startupResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
+    if (startupResult != 0) {
+      printf("WSAStartup failed with error: %d\n", startupResult);
+    }
+#endif
+
+    memset(&hints, 0, sizeof hints);
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+
+    if ((rv = getaddrinfo("localhost", std::to_string(port).c_str(), &hints,
+                          &servinfo)) != 0) {
+      std::cerr << "getaddrinfo: " << gai_strerror(rv) << "\n";
+      goto giveup;
+    }
+
+    // loop through all the results and connect to the first we can
+    for (p = servinfo; p != NULL; p = p->ai_next) {
+      if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
+        // errno is set here, but we don't examine it.
+        continue;
+      }
+
+      if (::connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
+#ifdef WIN32
+        closesocket(sockfd);
+#else
+        close(sockfd);
+#endif
+        // errno is set here, but we don't examine it.
+        continue;
+      }
+
+      break;
+    }
+
+    // Connection failed; give up.
+    if (p == NULL) {
+      goto giveup;
+    }
+
+    freeaddrinfo(servinfo);  // all done with this structure
+
+    _connected = true;
+
+    return;
+giveup:
+    _connected = false;
+    return;
+
+  }
+
+  // sends START_SENDING message to the Profiler with a model name
+  void start(const std::string& file_path = "",
+               int execution_id = -1, bool has_restarts = false) {
+    /// extract fzn file name
+    std::string base_name(file_path);
+    {
+      size_t pos = base_name.find_last_of('/');
+      if (pos != static_cast<size_t>(-1)) {
+        base_name = base_name.substr(pos + 1, base_name.length() - pos - 1);
+      }
+    }
+
+    std::string info{""};
+    {
+      std::stringstream ss;
+      ss << "{";
+      ss << "\"has_restarts\": " << (has_restarts ? "true" : "false")  << "\n";
+      ss << ",\"name\": " << "\"" << base_name << "\"" << "\n";
+      if (execution_id != -1) {
+        ss << ",\"execution_id\": " << execution_id;
+      }
+      ss << "}";
+      info = ss.str();
+    }
+
+    marshalling.makeStart(info);
+    sendOverSocket();
+  }
+
+  void restart(int restart_id = -1) {
+
+    std::string info{""};
+    {
+      std::stringstream ss;
+      ss << "{";
+      ss << "\"restart_id\": " << restart_id << "\n";
+      ss << "}";
+      info = ss.str();
+    }
+
+    marshalling.makeRestart(info);
+    sendOverSocket();
+  }
+
+  void done() {
+    marshalling.makeDone();
+    sendOverSocket();
+  }
+
+  /// disconnect from a socket
+  void disconnect() {
+#ifdef WIN32
+    closesocket(sockfd);
+#else
+    close(sockfd);
+#endif
+  }
+
+  void sendNode(const Node& node) {
+    if (!_connected) return;
+
+    auto& msg = marshalling.makeNode(node.nodeUID(), node.parentUID(),
+                                     node.alt(), node.kids(), node.status());
+
+    if (node.label().valid()) msg.set_label(node.label().value());
+    if (node.nogood().valid()) msg.set_nogood(node.nogood().value());
+    if (node.info().valid()) msg.set_info(node.info().value());
+
+    sendOverSocket();
+  }
+
+  Node createNode(NodeUID node, NodeUID parent,
+                  int alt, int kids, NodeStatus status) {
+    return Node(node, parent, alt, kids, status, *this);
+  }
+};
+
+void sendNode(Connector& c, Node& node) { c.sendNode(node); }
+
+}
+
+#endif
Index: minizinc-ide-2.5.0/cp-profiler/src/cpp-integration/message.hpp
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ minizinc-ide-2.5.0/cp-profiler/src/cpp-integration/message.hpp	2020-10-17 16:10:56.907395651 +0300
@@ -0,0 +1,328 @@
+#ifndef MESSAGE_HH
+#define MESSAGE_HH
+
+#include <vector>
+#include <string>
+#include <cassert>
+#include <cstdint>
+
+namespace cpprofiler {
+
+static const int32_t PROFILER_PROTOCOL_VERSION = 3;
+
+enum NodeStatus {
+  SOLVED = 0,        ///< Node representing a solution
+  FAILED = 1,        ///< Node representing failure
+  BRANCH = 2,        ///< Node representing a branch
+  SKIPPED = 3,       ///< Skipped by backjumping
+};
+
+enum class MsgType {
+  NODE = 0,
+  DONE = 1,
+  START = 2,
+  RESTART = 3,
+};
+
+// Unique identifier for a node
+struct NodeUID {
+  // Node number
+  int32_t nid;
+  // Restart id
+  int32_t rid;
+  // Thread id
+  int32_t tid;
+};
+
+
+class Message {
+  MsgType _type;
+
+  NodeUID _node;
+  NodeUID _parent;
+  int32_t _alt;
+  int32_t _kids;
+  NodeStatus _status;
+
+  bool _have_label{false};
+  std::string _label;
+
+  bool _have_nogood{false};
+  std::string _nogood;
+
+  bool _have_info{false};
+  std::string _info;
+
+  bool _have_version{false};
+  int32_t _version; // PROFILER_PROTOCOL_VERSION;
+
+public:
+  bool isNode(void) const { return _type == MsgType::NODE; }
+  bool isDone(void) const { return _type == MsgType::DONE; }
+  bool isStart(void) const { return _type == MsgType::START; }
+  bool isRestart(void) const { return _type == MsgType::RESTART; }
+
+  NodeUID nodeUID(void) const { return _node; }
+  void set_nodeUID(const NodeUID& n) { _node = n; }
+
+  NodeUID parentUID(void) const { return _parent; }
+  void set_parentUID(const NodeUID& p) { _parent = p; }
+
+  int32_t alt(void) const { return _alt; }
+  void set_alt(int32_t alt) { _alt = alt; }
+
+  int32_t kids(void) const { return _kids; }
+  void set_kids(int32_t kids) { _kids = kids; }
+
+  NodeStatus status(void) const { return _status; }
+  void set_status(NodeStatus status) { _status = status; }
+
+  void set_label(const std::string& label) {
+    _have_label = true;
+    _label = label;
+  }
+
+  void set_info(const std::string& info) {
+    _have_info = true;
+    _info = info;
+  }
+
+  void set_nogood(const std::string& nogood) {
+    _have_nogood = true;
+    _nogood = nogood;
+  }
+
+  void set_version(int32_t v) {
+    _have_version = true;
+    _version = v;
+  }
+
+  bool has_version(void) const { return _have_version; }
+  int32_t version(void) const { return _version; }
+
+  bool has_label(void) const { return _have_label; }
+  const std::string& label() const { return _label; }
+
+  bool has_nogood(void) const { return _have_nogood; }
+  const std::string& nogood(void) const { return _nogood; }
+
+  // generic optional fields
+  bool has_info(void) const { return _have_info; }
+  const std::string& info(void) const { return _info; }
+
+  void set_type(MsgType type) { _type = type; }
+  MsgType type(void) const { return _type; }
+
+  void reset(void) {
+    _have_label = false;
+    _have_nogood = false;
+    _have_info = false;
+    _have_version = false;
+  }
+};
+
+
+class MessageMarshalling {
+
+private:
+  /// Only optional fields are listed here, if node (no need for field id)
+  enum Field {
+    LABEL = 0,
+    NOGOOD = 1,
+    INFO = 2,
+    VERSION = 3
+  };
+
+  Message msg;
+
+  typedef char* iter;
+
+  static void serializeType(std::vector<char>& data, MsgType f) {
+    data.push_back(static_cast<char>(f));
+  }
+
+  static void serializeField(std::vector<char>& data, Field f) {
+    data.push_back(static_cast<char>(f));
+  }
+
+  static void serialize(std::vector<char>& data, int32_t i) {
+    data.push_back(static_cast<char>((i & 0xFF000000) >> 24));
+    data.push_back(static_cast<char>((i & 0xFF0000) >> 16));
+    data.push_back(static_cast<char>((i & 0xFF00) >> 8));
+    data.push_back(static_cast<char>((i & 0xFF)));
+  }
+
+  static void serialize(std::vector<char>& data, NodeStatus s) {
+    data.push_back(static_cast<char>(s));
+  }
+
+  static void serialize(std::vector<char>& data, const std::string& s) {
+    serialize(data, static_cast<int32_t>(s.size()));
+    for (char c : s) {
+      data.push_back(c);
+    }
+  }
+
+  static MsgType deserializeMsgType(iter& it) {
+    auto m = static_cast<MsgType>(*it);
+    ++it;
+    return m;
+  }
+
+  static Field deserializeField(iter& it) {
+    auto f = static_cast<Field>(*it);
+    ++it;
+    return f;
+  }
+
+  static int32_t deserializeInt(iter& it) {
+    auto b1 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
+    auto b2 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
+    auto b3 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
+    auto b4 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
+
+    return static_cast<int32_t>(b1 << 24 | b2 << 16 | b3 << 8 | b4);
+  }
+
+  static NodeStatus deserializeStatus(iter& it) {
+    auto f = static_cast<NodeStatus>(*it);
+    ++it;
+    return f;
+  }
+
+  static std::string deserializeString(iter& it) {
+    std::string result;
+    int32_t size = deserializeInt(it);
+    result.reserve(static_cast<size_t>(size));
+    for (int32_t i = 0; i < size; i++) {
+      result += *it;
+      ++it;
+    }
+    return result;
+  }
+
+public:
+  Message& makeNode(NodeUID node, NodeUID parent,
+                    int32_t alt, int32_t kids, NodeStatus status) {
+    msg.reset();
+    msg.set_type(MsgType::NODE);
+
+    msg.set_nodeUID(node);
+    msg.set_parentUID(parent);
+
+    msg.set_alt(alt);
+    msg.set_kids(kids);
+    msg.set_status(status);
+
+    return msg;
+  }
+
+  void makeStart(const std::string& info) {
+    msg.reset();
+    msg.set_type(MsgType::START);
+    msg.set_version(PROFILER_PROTOCOL_VERSION);
+    msg.set_info(info); /// info containts name, has_restarts, execution id
+  }
+
+  void makeRestart(const std::string& info) {
+    msg.reset();
+    msg.set_type(MsgType::RESTART);
+    msg.set_info(info); /// info contains restart_id (-1 default)
+  }
+
+  void makeDone(void) {
+    msg.reset();
+    msg.set_type(MsgType::DONE);
+  }
+
+  const Message& get_msg(void) { return msg; }
+
+  std::vector<char> serialize(void) const {
+    std::vector<char> data;
+    size_t dataSize = 1 + (msg.isNode() ? 4 * 8 + 1 : 0) +
+        (msg.has_label() ? 1 + 4 + msg.label().size() : 0) +
+        (msg.has_nogood() ? 1 + 4 + msg.nogood().size() : 0) +
+        (msg.has_info() ? 1 + 4 + msg.info().size() : 0);
+    data.reserve(dataSize);
+
+    serializeType(data, msg.type());
+    if (msg.isNode()) {
+      // serialize NodeId node
+      auto n_uid = msg.nodeUID();
+      serialize(data, n_uid.nid);
+      serialize(data, n_uid.rid);
+      serialize(data, n_uid.tid);
+      // serialize NodeId parent
+      auto p_uid = msg.parentUID();
+      serialize(data, p_uid.nid);
+      serialize(data, p_uid.rid);
+      serialize(data, p_uid.tid);
+      // Other Data
+      serialize(data, msg.alt());
+      serialize(data, msg.kids());
+      serialize(data, msg.status());
+    }
+
+    if(msg.has_version()) {
+      serializeField(data, VERSION);
+      serialize(data, msg.version());
+    }
+    if (msg.has_label()) {
+      serializeField(data, LABEL);
+      serialize(data, msg.label());
+    }
+    if (msg.has_nogood()) {
+      serializeField(data, NOGOOD);
+      serialize(data, msg.nogood());
+    }
+    if (msg.has_info()) {
+      serializeField(data, INFO);
+      serialize(data, msg.info());
+    }
+    return data;
+  }
+
+  void deserialize(char* data, size_t size) {
+    char *end = data + size;
+    msg.set_type(deserializeMsgType(data));
+    if (msg.isNode()) {
+      int32_t nid = deserializeInt(data);
+      int32_t rid = deserializeInt(data);
+      int32_t tid = deserializeInt(data);
+
+      msg.set_nodeUID({nid, rid, tid});
+
+      nid = deserializeInt(data);
+      rid = deserializeInt(data);
+      tid = deserializeInt(data);
+
+      msg.set_parentUID({nid, rid, tid});
+
+      msg.set_alt(deserializeInt(data));
+      msg.set_kids(deserializeInt(data));
+      msg.set_status(deserializeStatus(data));
+    }
+
+    msg.reset();
+
+    while (data != end) {
+      MessageMarshalling::Field f = deserializeField(data);
+      switch (f) {
+      case VERSION:
+        msg.set_version(deserializeInt(data)); break;
+      case LABEL:
+        msg.set_label(deserializeString(data)); break;
+      case NOGOOD:
+        msg.set_nogood(deserializeString(data)); break;
+      case INFO:
+        msg.set_info(deserializeString(data)); break;
+      default:
+        break;
+      }
+    }
+  }
+};
+
+}
+
+#endif  // MESSAGE_HH
